From bae24932f61d7e1e2a88fa45dcc86649377d6f7f Mon Sep 17 00:00:00 2001 From: Hraban Luyat Date: Sun, 5 Jul 2015 12:27:01 +0100 Subject: [PATCH] Add 16 bit codec apis --- decoder.go | 20 +++++++++++++++++++- encoder.go | 19 ++++++++++++++++++- opus_test.go | 46 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/decoder.go b/decoder.go index f51db8a..6b78909 100644 --- a/decoder.go +++ b/decoder.go @@ -33,11 +33,29 @@ func NewDecoder(sample_rate int, channels int) (*Decoder, error) { 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, diff --git a/encoder.go b/encoder.go index 483de73..53249e9 100644 --- a/encoder.go +++ b/encoder.go @@ -28,12 +28,29 @@ func NewEncoder(sample_rate int, channels int, application Application) (*Encode 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]), diff --git a/opus_test.go b/opus_test.go index 29f8a75..5cc3adc 100644 --- a/opus_test.go +++ b/opus_test.go @@ -38,26 +38,33 @@ func TestDecoderNew(t *testing.T) { } } -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) } @@ -65,7 +72,7 @@ func TestCodecFloat32(t *testing.T) { 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) } @@ -76,3 +83,32 @@ func TestCodecFloat32(t *testing.T) { // 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)) + } +} -- 2.48.1