audio/vorbis: Add decoded.readUntil

This commit is contained in:
Hajime Hoshi 2016-11-29 03:37:43 +09:00
parent 5789ad6920
commit 83f19591ca

View File

@ -31,6 +31,32 @@ type decoded struct {
decoder *oggvorbis.Reader decoder *oggvorbis.Reader
} }
func (d *decoded) readUntil(posInBytes int) error {
c := 0
for len(d.data) < posInBytes/2 {
// TODO: What if the channel is closed?
buffer := make([]float32, 4096)
n, err := d.decoder.Read(buffer)
if n > 0 {
d.data = append(d.data, buffer[:n]...)
}
if err == io.EOF {
if err := d.source.Close(); err != nil {
return err
}
break
}
if err != nil {
return err
}
c++
if c%4 == 0 {
runtime.Gosched()
}
}
return nil
}
func (d *decoded) Read(b []byte) (int, error) { func (d *decoded) Read(b []byte) (int, error) {
total := d.totalBytes total := d.totalBytes
l := total - d.posInBytes l := total - d.posInBytes
@ -42,23 +68,9 @@ func (d *decoded) Read(b []byte) (int, error) {
} }
// l must be even so that d.posInBytes is always even. // l must be even so that d.posInBytes is always even.
l = l / 2 * 2 l = l / 2 * 2
for len(d.data) < (d.posInBytes+l)/2 { if err := d.readUntil(d.posInBytes + l); err != nil {
// TODO: What if the channel is closed?
buffer := make([]float32, 4096)
n, err := d.decoder.Read(buffer)
if n > 0 {
d.data = append(d.data, buffer[:n]...)
}
if err == io.EOF {
if err := d.source.Close(); err != nil {
return 0, err return 0, err
} }
break
}
if err != nil {
return 0, err
}
}
for i := 0; i < l/2; i++ { for i := 0; i < l/2; i++ {
f := d.data[d.posInBytes/2+i] f := d.data[d.posInBytes/2+i]
s := int16(f * (1<<15 - 1)) s := int16(f * (1<<15 - 1))
@ -82,7 +94,12 @@ func (d *decoded) Seek(offset int64, whence int) (int64, error) {
case io.SeekEnd: case io.SeekEnd:
next = int64(d.totalBytes) + offset next = int64(d.totalBytes) + offset
} }
// pos should be always even
next = next / 2 * 2
d.posInBytes = int(next) d.posInBytes = int(next)
if err := d.readUntil(d.posInBytes); err != nil {
return 0, err
}
return next, nil return next, nil
} }