]> Sergey Matveev's repositories - go-opus.git/commitdiff
.Init method for preallocated codecs
authorHraban Luyat <hraban@0brg.net>
Sun, 5 Jul 2015 13:42:05 +0000 (14:42 +0100)
committerHraban Luyat <hraban@0brg.net>
Sun, 5 Jul 2015 13:42:05 +0000 (14:42 +0100)
decoder.go
encoder.go
opus_test.go

index 14acf981d22b68e57918311e2717944a6c7058b3..16b26288fe1e4895a1b47724d9846e6433883241 100644 (file)
@@ -15,6 +15,8 @@ import (
 */
 import "C"
 
+var errDecUninitialized = fmt.Errorf("opus decoder uninitialized")
+
 type Decoder struct {
        p *C.struct_OpusDecoder
        // Same purpose as encoder struct
@@ -25,11 +27,23 @@ type Decoder 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(
@@ -37,12 +51,15 @@ func NewDecoder(sample_rate int, channels int) (*Decoder, error) {
                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")
        }
@@ -62,6 +79,9 @@ func (dec *Decoder) Decode(data []byte) ([]int16, error) {
 }
 
 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")
        }
index 21467f85f7d1d670b8a913990de0a025f2542388..54383730ee8fbf620ee68f119565e9ca9c8be384 100644 (file)
@@ -15,6 +15,10 @@ import (
 */
 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
@@ -25,25 +29,41 @@ type Encoder struct {
 // 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")
        }
@@ -62,6 +82,9 @@ func (enc *Encoder) Encode(pcm []int16) ([]byte, error) {
 }
 
 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")
        }
index bdab063c6d98bdd0032125e9338ffd372f0b9445..c0d0eada007a0f81595a4cacaac5dd5e7817676f 100644 (file)
@@ -38,6 +38,30 @@ func TestDecoderNew(t *testing.T) {
        }
 }
 
+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