return dec, nil
}
-func (dec *Decoder) DecodeFloat32(data []byte) ([]float32, error) {
+func (dec *Decoder) Decode(data []byte) ([]int16, error) {
if data == nil || len(data) == 0 {
return nil, fmt.Errorf("opus: no data supplied")
}
// 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.opus_int32(len(data)),
+ (*C.opus_int16)(&pcm[0]),
+ C.int(cap(pcm)),
+ 0))
+ if n < 0 {
+ return nil, opuserr(n)
+ }
+ return pcm[:n], nil
+}
+
+func (dec *Decoder) DecodeFloat32(data []byte) ([]float32, error) {
+ if data == nil || len(data) == 0 {
+ return nil, fmt.Errorf("opus: no data supplied")
+ }
pcm := make([]float32, xMAX_FRAME_SIZE_MS*dec.sample_rate/1000)
n := int(C.opus_decode_float(
dec.p,
return &Encoder{p: p}, nil
}
-func (enc *Encoder) EncodeFloat32(pcm []float32) ([]byte, error) {
+func (enc *Encoder) Encode(pcm []int16) ([]byte, error) {
if pcm == nil || len(pcm) == 0 {
return nil, fmt.Errorf("opus: no data supplied")
}
// I never know how much to allocate
data := make([]byte, 10000)
+ n := int(C.opus_encode(
+ enc.p,
+ (*C.opus_int16)(&pcm[0]),
+ C.int(len(pcm)),
+ (*C.uchar)(&data[0]),
+ C.opus_int32(cap(data))))
+ if n < 0 {
+ return nil, opuserr(n)
+ }
+ return data[:n], nil
+}
+
+func (enc *Encoder) EncodeFloat32(pcm []float32) ([]byte, error) {
+ if pcm == nil || len(pcm) == 0 {
+ return nil, fmt.Errorf("opus: no data supplied")
+ }
+ data := make([]byte, 10000)
n := int(C.opus_encode_float(
enc.p,
(*C.float)(&pcm[0]),
}
}
-func addSine(buf []float32, sampleRate int, freq float64) {
+func addSineFloat32(buf []float32, sampleRate int, freq float64) {
factor := 2 * math.Pi * freq / float64(sampleRate)
for i := range buf {
buf[i] += float32(math.Sin(float64(i) * factor))
}
}
-func TestCodecFloat32(t *testing.T) {
+func addSine(buf []int16, sampleRate int, freq float64) {
+ factor := 2 * math.Pi * freq / float64(sampleRate)
+ for i := range buf {
+ buf[i] += int16(math.Sin(float64(i)*factor) * math.MaxInt16)
+ }
+}
+
+func TestCodec(t *testing.T) {
// Create bogus input sound
const G4 = 391.995
const SAMPLE_RATE = 48000
const FRAME_SIZE_MS = 60
const FRAME_SIZE = SAMPLE_RATE * FRAME_SIZE_MS / 1000
- pcm := make([]float32, FRAME_SIZE)
+ pcm := make([]int16, FRAME_SIZE)
enc, err := NewEncoder(SAMPLE_RATE, 1, APPLICATION_VOIP)
if err != nil || enc == nil {
t.Fatalf("Error creating new encoder: %v", err)
}
addSine(pcm, SAMPLE_RATE, G4)
- data, err := enc.EncodeFloat32(pcm)
+ data, err := enc.Encode(pcm)
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)
+ pcm2, err := dec.Decode(data)
if err != nil {
t.Fatalf("Couldn't decode data: %v", err)
}
// by hand and by ear, it looks fine. I'll just assume the API faithfully
// passes error codes through, and that's that.
}
+
+func TestCodecFloat32(t *testing.T) {
+ // Create bogus input sound
+ const G4 = 391.995
+ const SAMPLE_RATE = 48000
+ const FRAME_SIZE_MS = 60
+ const FRAME_SIZE = SAMPLE_RATE * FRAME_SIZE_MS / 1000
+ pcm := make([]float32, FRAME_SIZE)
+ enc, err := NewEncoder(SAMPLE_RATE, 1, APPLICATION_VOIP)
+ if err != nil || enc == nil {
+ t.Fatalf("Error creating new encoder: %v", err)
+ }
+ addSineFloat32(pcm, SAMPLE_RATE, G4)
+ data, err := enc.EncodeFloat32(pcm)
+ if err != nil {
+ t.Fatalf("Couldn't encode data: %v", err)
+ }
+ dec, err := NewDecoder(SAMPLE_RATE, 1)
+ if err != nil || dec == nil {
+ t.Fatalf("Error creating new decoder: %v", err)
+ }
+ pcm2, err := dec.DecodeFloat32(data)
+ 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))
+ }
+}