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 }