func TestNsf(t *testing.T) { f, err := os.Open("mm3.nsf") if err != nil { t.Fatal(err) } n, err := ReadNSF(f) if err != nil { t.Fatal(err) } if n.LoadAddr != 0x8000 || n.InitAddr != 0x8003 || n.PlayAddr != 0x8000 { t.Fatal("bad addresses") } n.Init(1) o, err := output.NewPort(int(n.SampleRate), 1) if err != nil { t.Fatal(err) } const div = 10 ns := int(n.SampleRate / div) for { o.Push(n.Play(ns)) } }
func (srv *Server) audio() { var o output.Output var t chan interface{} var err error var present bool var dur time.Duration stop := func() { log.Println("stop") t = nil srv.Song = nil } tick := func() { if srv.Elapsed > srv.Info.Time { stop() } if srv.Song == nil { if len(srv.Playlist) == 0 { log.Println("empty playlist") stop() return } else if srv.PlaylistIndex >= len(srv.Playlist) { if srv.Repeat { srv.PlaylistIndex = 0 } else { log.Println("end of playlist") stop() return } } srv.Song, present = srv.Songs[srv.Playlist[srv.PlaylistIndex]] srv.PlaylistIndex++ if !present { return } info := srv.Song.Info() if info.SampleRate != srv.Info.SampleRate || info.Channels != srv.Info.Channels { if o != nil { println(4) o.Dispose() } o, err = output.NewPort(info.SampleRate, info.Channels) if err != nil { log.Println(fmt.Errorf("mog: could not open audio (%v, %v): %v", info.SampleRate, info.Channels, err)) } } srv.Info = info srv.Elapsed = 0 dur = time.Second / (time.Duration(srv.Info.SampleRate)) t = make(chan interface{}) close(t) } const expected = 4096 next := srv.Song.Play(expected) srv.Elapsed += time.Duration(len(next)) * dur if len(next) > 0 { o.Push(next) } if len(next) < expected { stop() } } play := func() { log.Println("play") tick() } for { select { case <-t: tick() case cmd := <-srv.ch: switch cmd { case cmdPlay: play() case cmdStop: stop() default: log.Fatal("unknown command") } } } }