From 643592f692bf8276a3718f7305bd774c5f59a092 Mon Sep 17 00:00:00 2001 From: Hraban Luyat Date: Sun, 5 Jul 2015 14:23:15 +0100 Subject: [PATCH] Let Go GC manage the codec memory No need to manually free memory anymore --- decoder.go | 37 ++++++++++++++++++------------------- encoder.go | 33 +++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/decoder.go b/decoder.go index 6b78909..14acf98 100644 --- a/decoder.go +++ b/decoder.go @@ -16,21 +16,30 @@ import ( import "C" type Decoder struct { - p *C.struct_OpusDecoder + p *C.struct_OpusDecoder + // Same purpose as encoder struct + mem []byte sample_rate int } +// 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 errno int - p := C.opus_decoder_create(C.opus_int32(sample_rate), C.int(channels), (*C.int)(unsafe.Pointer(&errno))) - if errno != 0 { - return nil, opuserr(errno) + if channels != 1 && channels != 2 { + return nil, fmt.Errorf("Number of channels must be 1 or 2: %d", channels) } - dec := &Decoder{ - p: p, - sample_rate: sample_rate, + dec := Decoder{sample_rate: sample_rate} + size := C.opus_decoder_get_size(C.int(channels)) + dec.mem = make([]byte, size) + dec.p = (*C.OpusDecoder)(unsafe.Pointer(&dec.mem[0])) + errno := C.opus_decoder_init( + dec.p, + C.opus_int32(sample_rate), + C.int(channels)) + if errno != 0 { + return nil, opuserr(int(errno)) } - return dec, nil + return &dec, nil } func (dec *Decoder) Decode(data []byte) ([]int16, error) { @@ -69,13 +78,3 @@ func (dec *Decoder) DecodeFloat32(data []byte) ([]float32, error) { } return pcm[:n], nil } - -// Returns an error if the encoder was already closed -func (dec *Decoder) Close() error { - if dec.p == nil { - return fmt.Errorf("opus: decoder already closed") - } - C.opus_decoder_destroy(dec.p) - dec.p = nil - return nil -} diff --git a/encoder.go b/encoder.go index 53249e9..21467f8 100644 --- a/encoder.go +++ b/encoder.go @@ -17,15 +17,30 @@ import "C" type Encoder struct { p *C.struct_OpusEncoder + // Memory for the encoder struct allocated on the Go heap to allow Go GC to + // manage it (and obviate need to free()) + mem []byte } +// 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 errno int - p := C.opus_encoder_create(C.opus_int32(sample_rate), C.int(channels), C.int(application), (*C.int)(unsafe.Pointer(&errno))) + if channels != 1 && channels != 2 { + return nil, 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])) + errno := int(C.opus_encoder_init( + e.p, + C.opus_int32(sample_rate), + C.int(channels), + C.int(application))) if errno != 0 { - return nil, opuserr(errno) + return nil, opuserr(int(errno)) } - return &Encoder{p: p}, nil + return &e, nil } func (enc *Encoder) Encode(pcm []int16) ([]byte, error) { @@ -62,13 +77,3 @@ func (enc *Encoder) EncodeFloat32(pcm []float32) ([]byte, error) { } return data[:n], nil } - -// Returns an error if the encoder was already closed -func (enc *Encoder) Close() error { - if enc.p == nil { - return fmt.Errorf("opus: encoder already closed") - } - C.opus_encoder_destroy(enc.p) - enc.p = nil - return nil -} -- 2.48.1