Пример #1
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")
			}
		}
	}
}
Пример #2
0
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")
			}
		}
	}
}