예제 #1
0
func PlayPath(p string, vis Visualizer) error {
	var song codec.Song

	songs, _, err := codec.ByExtension(p, fileReader(p))
	if err != nil {
		return err
	}
	for _, song = range songs {
		// Get first song
		break
	}
	sampleRate, channels, err := song.Init()
	if err != nil {
		return err
	}
	defer song.Close()
	seekRate := int(sampleRate / 10.0) // fps
	vis.SetFreq(float64(seekRate))

	out, err := output.Get(sampleRate, channels)
	if err != nil {
		return err
	}
	out.Start()

	for {
		samples, err := song.Play(seekRate)
		if err != nil {
			return err
		}

		out.Push(samples)
		vis.Push(samples)
		if len(samples) < seekRate {
			// Done
			break
		}
	}

	return nil
}
예제 #2
0
파일: audio.go 프로젝트: shazow/mog
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")
			}
		}
	}
}