1
0
Fork 0
huge-piano/audio.go

97 lines
1.6 KiB
Go
Raw Permalink Normal View History

2018-04-06 23:39:07 +08:00
package main
import (
"io/ioutil"
2018-04-07 06:36:25 +08:00
"log"
2018-04-06 23:39:07 +08:00
"os"
2018-04-07 06:36:25 +08:00
"path"
2018-04-06 23:39:07 +08:00
"sort"
2018-04-07 06:36:25 +08:00
"strings"
2018-04-06 23:39:07 +08:00
"time"
"github.com/faiface/beep"
"github.com/faiface/beep/speaker"
"github.com/faiface/beep/wav"
)
type audio struct {
play chan int
packDir string
sampleRate beep.SampleRate
2018-04-07 06:36:25 +08:00
pack []beep.StreamSeeker
2018-04-06 23:39:07 +08:00
}
2018-04-07 06:36:25 +08:00
func (a *audio) load() {
2018-04-06 23:39:07 +08:00
a.loadStreamers()
a.initSpeaker()
}
2018-04-07 06:36:25 +08:00
func (a *audio) initSpeaker() {
speaker.Init(a.sampleRate, a.sampleRate.N(time.Second/10))
2018-04-06 23:39:07 +08:00
}
2018-04-07 06:36:25 +08:00
func (a *audio) loadStreamers() {
2018-04-06 23:39:07 +08:00
files, err := ioutil.ReadDir(a.packDir)
if err != nil {
panic(err)
}
sort.Sort(byFileInfoName(files))
for _, file := range files {
2018-04-07 06:36:25 +08:00
if !strings.HasSuffix(file.Name(), ".wav") {
2018-04-06 23:39:07 +08:00
continue
}
2018-04-07 06:36:25 +08:00
a.loadStreamer(path.Join(a.packDir, file.Name()))
2018-04-06 23:39:07 +08:00
}
}
2018-04-07 06:36:25 +08:00
func (a *audio) loadStreamer(fn string) {
log.Printf("Loading file %d: %s", len(a.pack), fn)
2018-04-06 23:39:07 +08:00
f, err := os.Open(fn)
if err != nil {
panic(err)
}
s, format, err := wav.Decode(f)
if err != nil {
panic(err)
}
a.pack = append(a.pack, s)
a.sampleRate = format.SampleRate
}
2018-04-07 06:36:25 +08:00
func (a *audio) playSample(i int) {
a.pack[i].Seek(0)
2018-04-06 23:39:07 +08:00
speaker.Play(a.pack[i])
}
2018-04-07 06:36:25 +08:00
func (a *audio) watch() {
log.Println("Awaiting for audio...")
for play := range a.play {
2018-04-06 23:39:07 +08:00
a.playSample(play)
}
2018-04-07 06:36:25 +08:00
log.Println("No more incoming audio")
2018-04-06 23:39:07 +08:00
}
2018-04-07 06:36:25 +08:00
func newAudio(play chan int, packDir string) *audio {
a := &audio{
2018-04-06 23:39:07 +08:00
play: play,
packDir: packDir,
}
a.load()
return a
}
type byFileInfoName []os.FileInfo
func (f byFileInfoName) Len() int {
return len(f)
}
func (f byFileInfoName) Swap(i, j int) {
f[i], f[j] = f[j], f[i]
}
func (f byFileInfoName) Less(i, j int) bool {
return f[i].Name() < f[j].Name()
}