Beispiel #1
0
func (p *Player) prepare(offset int64, force bool) error {
	p.mu.Lock()
	if !force && p.prep {
		p.mu.Unlock()
		return nil
	}
	p.mu.Unlock()

	if p.t.hasHeader {
		offset += headerSize
	}
	if _, err := p.t.src.Seek(offset, 0); err != nil {
		return err
	}
	var 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(formatCodes[p.t.format], buf[:n], int32(p.t.samplesPerSecond))
			bufs = append(bufs, b[0])
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
	}

	p.mu.Lock()
	if len(p.bufs) > 0 {
		p.source.UnqueueBuffers(p.bufs)
		al.DeleteBuffers(p.bufs)
	}
	p.sizeBytes = size
	p.bufs = bufs
	p.prep = true
	if len(bufs) > 0 {
		p.source.QueueBuffers(bufs)
	}
	p.mu.Unlock()
	return nil
}
Beispiel #2
0
// Close closes the device and frees the underlying resources
// used by the player.
// It should be called as soon as the player is not in-use anymore.
func (p *Player) Close() error {
	if p == nil {
		return nil
	}
	if p.source != 0 {
		al.DeleteSources(p.source)
	}
	p.mu.Lock()
	if len(p.bufs) > 0 {
		al.DeleteBuffers(p.bufs)
	}
	p.mu.Unlock()
	p.t.src.Close()
	return nil
}