88 lines
1.3 KiB
Go
88 lines
1.3 KiB
Go
|
package opus
|
||
|
|
||
|
import (
|
||
|
"io"
|
||
|
"log"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/faiface/beep"
|
||
|
"github.com/pkg/errors"
|
||
|
opusd "gopkg.in/hraban/opus.v2"
|
||
|
)
|
||
|
|
||
|
type decoder struct {
|
||
|
sync.Mutex
|
||
|
|
||
|
rc io.ReadSeekCloser
|
||
|
r *opusd.Stream
|
||
|
err error
|
||
|
}
|
||
|
|
||
|
func New(f io.ReadSeekCloser) (beep.StreamSeeker, error) {
|
||
|
d := new(decoder)
|
||
|
st, err := opusd.NewStream(f)
|
||
|
if err != nil {
|
||
|
return d, err
|
||
|
}
|
||
|
|
||
|
d.rc = f
|
||
|
d.r = st
|
||
|
|
||
|
return d, nil
|
||
|
}
|
||
|
|
||
|
func (s *decoder) Err() error { return s.err }
|
||
|
|
||
|
func (d *decoder) Stream(samples [][2]float64) (n int, ok bool) {
|
||
|
if d.err != nil {
|
||
|
return 0, false
|
||
|
}
|
||
|
var tmp [2]float32
|
||
|
for i := range samples {
|
||
|
dn, err := d.r.ReadFloat32(tmp[:])
|
||
|
|
||
|
if dn == 1 {
|
||
|
samples[i][0], samples[i][1] = float64(tmp[0]), float64(tmp[1])
|
||
|
n++
|
||
|
ok = true
|
||
|
}
|
||
|
if err == io.EOF {
|
||
|
ok = false
|
||
|
break
|
||
|
}
|
||
|
if err != nil {
|
||
|
ok = false
|
||
|
d.err = errors.Wrap(err, "ogg/opus")
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return n, ok
|
||
|
}
|
||
|
|
||
|
func (d *decoder) Len() int {
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
func (d *decoder) Position() int {
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
func (d *decoder) Seek(p int) error {
|
||
|
_, err := d.rc.Seek(int64(p), io.SeekStart)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return errors.Wrap(err, "ogg/opus")
|
||
|
}
|
||
|
|
||
|
st, err := opusd.NewStream(d.rc)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return errors.Wrap(err, "ogg/opus")
|
||
|
}
|
||
|
|
||
|
d.r = st
|
||
|
|
||
|
return nil
|
||
|
}
|