]> Sergey Matveev's repositories - go-opus.git/commitdiff
Add 16 bit codec apis
authorHraban Luyat <hraban@0brg.net>
Sun, 5 Jul 2015 11:27:01 +0000 (12:27 +0100)
committerHraban Luyat <hraban@0brg.net>
Sun, 5 Jul 2015 11:27:01 +0000 (12:27 +0100)
decoder.go
encoder.go
opus_test.go

index f51db8a582a24420526059ed4a69122a1617bd04..6b7890981d7b528ffc9aacf535d64362a7388443 100644 (file)
@@ -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,
index 483de73e46afebbe46d808b4a3764e2f6f7b1346..53249e9fb135df185adcd6c4fe2b24a076cca8e2 100644 (file)
@@ -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]),
index 29f8a75d6012240fc989e16d8a551e60b7b6317d..5cc3adcbcf4728f958b9ded6c849b0c6f7f6e694 100644 (file)
@@ -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))
+       }
+}