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