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") } } } }
func (srv *Server) audio() { var out output.Output var t chan interface{} var seek *Seek var dur time.Duration var err error send := func(v interface{}) { go func() { srv.ch <- v }() } setTime := func() { send(cmdSetTime(seek.Pos())) } tick := func() { const expected = 4096 if seek == nil { return } next, err := seek.Read(expected) if len(next) > 0 { out.Push(next) setTime() } if err != nil { seek = nil } if err == io.ErrUnexpectedEOF { send(cmdRestartSong) } else if err != nil { send(cmdNext) } } doSeek := func(c cmdSeek) { if seek == nil { return } err := seek.Seek(time.Duration(c)) if err != nil { send(cmdError(err)) return } setTime() } setParams := func(c audioSetParams) { out, err = output.Get(c.sr, c.ch) if err != nil { c.err <- fmt.Errorf("mog: could not open audio (%v, %v): %v", c.sr, c.ch, err) return } dur = time.Second / (time.Duration(c.sr * c.ch)) seek = NewSeek(c.dur > 0, dur, c.play) t = make(chan interface{}) close(t) c.err <- nil } for { select { case <-t: tick() case c := <-srv.audioch: log.Printf("%T\n", c) switch c := c.(type) { case audioStop: t = nil case audioPlay: t = make(chan interface{}) close(t) case audioSetParams: setParams(c) case cmdSeek: doSeek(c) default: panic("unknown type") } } } }