Beispiel #1
0
// NewPlayer returns a new Player.
// It initializes the underlying audio devices and the related resources.
func NewPlayer(src io.ReadSeeker, format Format, sampleRate int64) (*Player, error) {
	device.Lock()
	defer device.Unlock()

	if device.d == nil {
		device.d = alc.Open("")
		c := device.d.CreateContext(nil)
		if !alc.MakeContextCurrent(c) {
			return nil, fmt.Errorf("player: cannot initiate a new player")
		}
	}
	s := al.GenSources(1)
	if code := al.Error(); code != 0 {
		return nil, fmt.Errorf("player: cannot generate an audio source [err=%x]", code)
	}
	bufs := al.GenBuffers(2)
	if err := lastErr(); err != nil {
		return nil, err
	}
	return &Player{
		t:      &track{format: format, src: src, rate: sampleRate},
		source: s[0],
		bufs:   bufs,
	}, nil
}
Beispiel #2
0
func (p *Player) prepare(offset int64, force bool) error {
	p.muPrep.Lock()
	defer p.muPrep.Unlock()
	if !force && p.prep {
		return nil
	}
	if len(p.bufs) > 0 {
		p.source.UnqueueBuffers(p.bufs)
		al.DeleteBuffers(p.bufs)
	}
	if _, err := p.t.src.Seek(offset, 0); err != nil {
		return err
	}
	p.bufs = []al.Buffer{}
	// TODO(jbd): Limit the number of buffers in use, unqueue and reuse
	// the existing buffers as buffers are processed.
	buf := make([]byte, 128*1024)
	size := offset
	for {
		n, err := p.t.src.Read(buf)
		if n > 0 {
			size += int64(n)
			b := al.GenBuffers(1)
			b[0].BufferData(uint32(formatToCode[p.t.format]), buf[:n], int32(p.t.rate))
			p.bufs = append(p.bufs, b[0])
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
	}
	p.size = size
	if len(p.bufs) > 0 {
		p.source.QueueBuffers(p.bufs)
	}
	p.prep = true
	return nil
}