*/
import "C"
+var errDecUninitialized = fmt.Errorf("opus decoder uninitialized")
+
type Decoder struct {
p *C.struct_OpusDecoder
// Same purpose as encoder struct
// NewEncoder allocates a new Opus decoder and initializes it with the
// appropriate parameters. All related memory is managed by the Go GC.
func NewDecoder(sample_rate int, channels int) (*Decoder, error) {
+ var dec Decoder
+ err := dec.Init(sample_rate, channels)
+ if err != nil {
+ return nil, err
+ }
+ return &dec, nil
+}
+
+func (dec *Decoder) Init(sample_rate int, channels int) error {
+ if dec.p != nil {
+ return fmt.Errorf("opus decoder already initialized")
+ }
if channels != 1 && channels != 2 {
- return nil, fmt.Errorf("Number of channels must be 1 or 2: %d", channels)
+ return fmt.Errorf("Number of channels must be 1 or 2: %d", channels)
}
- dec := Decoder{sample_rate: sample_rate}
size := C.opus_decoder_get_size(C.int(channels))
+ dec.sample_rate = sample_rate
dec.mem = make([]byte, size)
dec.p = (*C.OpusDecoder)(unsafe.Pointer(&dec.mem[0]))
errno := C.opus_decoder_init(
C.opus_int32(sample_rate),
C.int(channels))
if errno != 0 {
- return nil, opuserr(int(errno))
+ return opuserr(int(errno))
}
- return &dec, nil
+ return nil
}
func (dec *Decoder) Decode(data []byte) ([]int16, error) {
+ if dec.p == nil {
+ return nil, errDecUninitialized
+ }
if data == nil || len(data) == 0 {
return nil, fmt.Errorf("opus: no data supplied")
}
}
func (dec *Decoder) DecodeFloat32(data []byte) ([]float32, error) {
+ if dec.p == nil {
+ return nil, errDecUninitialized
+ }
if data == nil || len(data) == 0 {
return nil, fmt.Errorf("opus: no data supplied")
}
*/
import "C"
+var errEncUninitialized = fmt.Errorf("opus encoder uninitialized")
+
+// Encoder contains the state of an Opus encoder for libopus. Do not use this
+// directly, but call
type Encoder struct {
p *C.struct_OpusEncoder
// Memory for the encoder struct allocated on the Go heap to allow Go GC to
// NewEncoder allocates a new Opus encoder and initializes it with the
// appropriate parameters. All related memory is managed by the Go GC.
func NewEncoder(sample_rate int, channels int, application Application) (*Encoder, error) {
+ var enc Encoder
+ err := enc.Init(sample_rate, channels, application)
+ if err != nil {
+ return nil, err
+ }
+ return &enc, nil
+}
+
+// Init initializes a pre-allocated opus encoder. Must be called exactly once in
+// the life-time of this object, before calling any other methods.
+func (enc *Encoder) Init(sample_rate int, channels int, application Application) error {
+ if enc.p != nil {
+ return fmt.Errorf("opus encoder already initialized")
+ }
if channels != 1 && channels != 2 {
- return nil, fmt.Errorf("Number of channels must be 1 or 2: %d", channels)
+ return fmt.Errorf("Number of channels must be 1 or 2: %d", channels)
}
- var e Encoder
size := C.opus_encoder_get_size(C.int(channels))
- e.mem = make([]byte, size)
- e.p = (*C.OpusEncoder)(unsafe.Pointer(&e.mem[0]))
+ enc.mem = make([]byte, size)
+ enc.p = (*C.OpusEncoder)(unsafe.Pointer(&enc.mem[0]))
errno := int(C.opus_encoder_init(
- e.p,
+ enc.p,
C.opus_int32(sample_rate),
C.int(channels),
C.int(application)))
if errno != 0 {
- return nil, opuserr(int(errno))
+ return opuserr(int(errno))
}
- return &e, nil
+ return nil
}
func (enc *Encoder) Encode(pcm []int16) ([]byte, error) {
+ if enc.p == nil {
+ return nil, errEncUninitialized
+ }
if pcm == nil || len(pcm) == 0 {
return nil, fmt.Errorf("opus: no data supplied")
}
}
func (enc *Encoder) EncodeFloat32(pcm []float32) ([]byte, error) {
+ if enc.p == nil {
+ return nil, errEncUninitialized
+ }
if pcm == nil || len(pcm) == 0 {
return nil, fmt.Errorf("opus: no data supplied")
}
}
}
+func TestEncoderUnitialized(t *testing.T) {
+ var enc Encoder
+ _, err := enc.Encode(nil)
+ if err != errEncUninitialized {
+ t.Errorf("Expected \"unitialized encoder\" error: %v", err)
+ }
+ _, err = enc.EncodeFloat32(nil)
+ if err != errEncUninitialized {
+ t.Errorf("Expected \"unitialized encoder\" error: %v", err)
+ }
+}
+
+func TestDecoderUnitialized(t *testing.T) {
+ var dec Decoder
+ _, err := dec.Decode(nil)
+ if err != errDecUninitialized {
+ t.Errorf("Expected \"unitialized decoder\" error: %v", err)
+ }
+ _, err = dec.DecodeFloat32(nil)
+ if err != errDecUninitialized {
+ t.Errorf("Expected \"unitialized decoder\" error: %v", err)
+ }
+}
+
func TestOpuserr(t *testing.T) {
// I scooped this -1 up from opus_defines.h, it's OPUS_BAD_ARG. Not pretty,
// but it's better than not testing at all. Again, accessing #defines from