Example #1
0
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))
	}
}
Example #2
0
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")
			}
		}
	}
}