From: Hraban Luyat <hraban@0brg.net>
Date: Sun, 5 Jul 2015 13:23:15 +0000 (+0100)
Subject: Let Go GC manage the codec memory
X-Git-Tag: v2.0.0~103
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=643592f692bf8276a3718f7305bd774c5f59a092;p=go-opus.git

Let Go GC manage the codec memory

No need to manually free memory anymore
---

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
-}