return nil
}
-func (dec *Decoder) Decode(data []byte) ([]int16, error) {
+// Decode encoded Opus data into the supplied buffer. On success, returns the
+// number of samples correctly written to the target buffer.
+func (dec *Decoder) Decode(data []byte, pcm []int16) (int, error) {
if dec.p == nil {
- return nil, errDecUninitialized
+ return 0, errDecUninitialized
}
- if data == nil || len(data) == 0 {
- return nil, fmt.Errorf("opus: no data supplied")
+ if len(data) == 0 {
+ return 0, fmt.Errorf("opus: no data supplied")
+ }
+ if len(pcm) == 0 {
+ return 0, fmt.Errorf("opus: target buffer empty")
}
- // I don't know how big this frame will be, but this is the limit
- pcm := make([]int16, xMAX_FRAME_SIZE_MS*dec.sample_rate/1000)
n := int(C.opus_decode(
dec.p,
(*C.uchar)(&data[0]),
C.int(cap(pcm)),
0))
if n < 0 {
- return nil, opuserr(n)
+ return 0, opuserr(n)
}
- return pcm[:n], nil
+ return n, nil
}
-func (dec *Decoder) DecodeFloat32(data []byte) ([]float32, error) {
+// Decode encoded Opus data into the supplied buffer. On success, returns the
+// number of samples correctly written to the target buffer.
+func (dec *Decoder) DecodeFloat32(data []byte, pcm []float32) (int, error) {
if dec.p == nil {
- return nil, errDecUninitialized
+ return 0, errDecUninitialized
+ }
+ if len(data) == 0 {
+ return 0, fmt.Errorf("opus: no data supplied")
}
- if data == nil || len(data) == 0 {
- return nil, fmt.Errorf("opus: no data supplied")
+ if len(pcm) == 0 {
+ return 0, fmt.Errorf("opus: target buffer empty")
}
- pcm := make([]float32, xMAX_FRAME_SIZE_MS*dec.sample_rate/1000)
n := int(C.opus_decode_float(
dec.p,
(*C.uchar)(&data[0]),
C.int(cap(pcm)),
0))
if n < 0 {
- return nil, opuserr(n)
+ return 0, opuserr(n)
}
- return pcm[:n], nil
+ return n, nil
}
return nil
}
-func (enc *Encoder) Encode(pcm []int16) ([]byte, error) {
+// Encode raw PCM data and store the result in the supplied buffer. On success,
+// returns the number of bytes used up by the encoded data.
+func (enc *Encoder) Encode(pcm []int16, data []byte) (int, error) {
if enc.p == nil {
- return nil, errEncUninitialized
+ return 0, errEncUninitialized
}
- if pcm == nil || len(pcm) == 0 {
- return nil, fmt.Errorf("opus: no data supplied")
+ if len(pcm) == 0 {
+ return 0, fmt.Errorf("opus: no data supplied")
+ }
+ if len(data) == 0 {
+ return 0, fmt.Errorf("opus: no target buffer")
}
- data := make([]byte, maxEncodedFrameSize)
n := int(C.opus_encode(
enc.p,
(*C.opus_int16)(&pcm[0]),
(*C.uchar)(&data[0]),
C.opus_int32(cap(data))))
if n < 0 {
- return nil, opuserr(n)
+ return 0, opuserr(n)
}
- return data[:n], nil
+ return n, nil
}
-func (enc *Encoder) EncodeFloat32(pcm []float32) ([]byte, error) {
+// Encode raw PCM data and store the result in the supplied buffer. On success,
+// returns the number of bytes used up by the encoded data.
+func (enc *Encoder) EncodeFloat32(pcm []float32, data []byte) (int, error) {
if enc.p == nil {
- return nil, errEncUninitialized
+ return 0, errEncUninitialized
+ }
+ if len(pcm) == 0 {
+ return 0, fmt.Errorf("opus: no data supplied")
}
- if pcm == nil || len(pcm) == 0 {
- return nil, fmt.Errorf("opus: no data supplied")
+ if len(data) == 0 {
+ return 0, fmt.Errorf("opus: no target buffer")
}
- data := make([]byte, maxEncodedFrameSize)
n := int(C.opus_encode_float(
enc.p,
(*C.float)(&pcm[0]),
(*C.uchar)(&data[0]),
C.opus_int32(cap(data))))
if n < 0 {
- return nil, opuserr(n)
+ return 0, opuserr(n)
}
- return data[:n], nil
+ return n, nil
}
func TestEncoderUnitialized(t *testing.T) {
var enc Encoder
- _, err := enc.Encode(nil)
+ _, err := enc.Encode(nil, nil)
if err != errEncUninitialized {
t.Errorf("Expected \"unitialized encoder\" error: %v", err)
}
- _, err = enc.EncodeFloat32(nil)
+ _, err = enc.EncodeFloat32(nil, nil)
if err != errEncUninitialized {
t.Errorf("Expected \"unitialized encoder\" error: %v", err)
}
func TestDecoderUnitialized(t *testing.T) {
var dec Decoder
- _, err := dec.Decode(nil)
+ _, err := dec.Decode(nil, nil)
if err != errDecUninitialized {
t.Errorf("Expected \"unitialized decoder\" error: %v", err)
}
- _, err = dec.DecodeFloat32(nil)
+ _, err = dec.DecodeFloat32(nil, nil)
if err != errDecUninitialized {
t.Errorf("Expected \"unitialized decoder\" error: %v", err)
}
t.Fatalf("Error creating new encoder: %v", err)
}
addSine(pcm, SAMPLE_RATE, G4)
- data, err := enc.Encode(pcm)
+ data := make([]byte, 1000)
+ n, err := enc.Encode(pcm, data)
if err != nil {
t.Fatalf("Couldn't encode data: %v", err)
}
+ data = data[:n]
dec, err := NewDecoder(SAMPLE_RATE, 1)
if err != nil || dec == nil {
t.Fatalf("Error creating new decoder: %v", err)
}
- pcm2, err := dec.Decode(data)
+ n, err = dec.Decode(data, pcm)
if err != nil {
t.Fatalf("Couldn't decode data: %v", err)
}
- if len(pcm) != len(pcm2) {
- t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), len(pcm2))
+ if len(pcm) != n {
+ t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), n)
}
// Checking the output programmatically is seriously not easy. I checked it
// by hand and by ear, it looks fine. I'll just assume the API faithfully
t.Fatalf("Error creating new encoder: %v", err)
}
addSineFloat32(pcm, SAMPLE_RATE, G4)
- data, err := enc.EncodeFloat32(pcm)
+ data := make([]byte, 1000)
+ n, err := enc.EncodeFloat32(pcm, data)
if err != nil {
t.Fatalf("Couldn't encode data: %v", err)
}
if err != nil || dec == nil {
t.Fatalf("Error creating new decoder: %v", err)
}
- pcm2, err := dec.DecodeFloat32(data)
+ n, err = dec.DecodeFloat32(data, pcm)
if err != nil {
t.Fatalf("Couldn't decode data: %v", err)
}
- if len(pcm) != len(pcm2) {
- t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), len(pcm2))
+ if len(pcm) != n {
+ t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), n)
}
}