1 // Copyright © Go Opus Authors (see AUTHORS file)
3 // License for use of this code is detailed in the LICENSE file
13 #cgo pkg-config: --static opus
18 bridge_encoder_set_dtx(OpusEncoder *st, opus_int32 use_dtx)
20 return opus_encoder_ctl(st, OPUS_SET_DTX(use_dtx));
24 bridge_encoder_get_dtx(OpusEncoder *st, opus_int32 *dtx)
26 return opus_encoder_ctl(st, OPUS_GET_DTX(dtx));
30 bridge_encoder_get_in_dtx(OpusEncoder *st, opus_int32 *in_dtx)
32 return opus_encoder_ctl(st, OPUS_GET_IN_DTX(in_dtx));
36 bridge_encoder_get_sample_rate(OpusEncoder *st, opus_int32 *sample_rate)
38 return opus_encoder_ctl(st, OPUS_GET_SAMPLE_RATE(sample_rate));
43 bridge_encoder_set_bitrate(OpusEncoder *st, opus_int32 bitrate)
45 return opus_encoder_ctl(st, OPUS_SET_BITRATE(bitrate));
49 bridge_encoder_get_bitrate(OpusEncoder *st, opus_int32 *bitrate)
51 return opus_encoder_ctl(st, OPUS_GET_BITRATE(bitrate));
55 bridge_encoder_set_complexity(OpusEncoder *st, opus_int32 complexity)
57 return opus_encoder_ctl(st, OPUS_SET_COMPLEXITY(complexity));
61 bridge_encoder_get_complexity(OpusEncoder *st, opus_int32 *complexity)
63 return opus_encoder_ctl(st, OPUS_GET_COMPLEXITY(complexity));
67 bridge_encoder_set_max_bandwidth(OpusEncoder *st, opus_int32 max_bw)
69 return opus_encoder_ctl(st, OPUS_SET_MAX_BANDWIDTH(max_bw));
73 bridge_encoder_get_max_bandwidth(OpusEncoder *st, opus_int32 *max_bw)
75 return opus_encoder_ctl(st, OPUS_GET_MAX_BANDWIDTH(max_bw));
79 bridge_encoder_set_inband_fec(OpusEncoder *st, opus_int32 fec)
81 return opus_encoder_ctl(st, OPUS_SET_INBAND_FEC(fec));
85 bridge_encoder_get_inband_fec(OpusEncoder *st, opus_int32 *fec)
87 return opus_encoder_ctl(st, OPUS_GET_INBAND_FEC(fec));
91 bridge_encoder_set_packet_loss_perc(OpusEncoder *st, opus_int32 loss_perc)
93 return opus_encoder_ctl(st, OPUS_SET_PACKET_LOSS_PERC(loss_perc));
97 bridge_encoder_get_packet_loss_perc(OpusEncoder *st, opus_int32 *loss_perc)
99 return opus_encoder_ctl(st, OPUS_GET_PACKET_LOSS_PERC(loss_perc));
103 bridge_encoder_reset_state(OpusEncoder *st)
105 return opus_encoder_ctl(st, OPUS_RESET_STATE);
115 Narrowband = Bandwidth(C.OPUS_BANDWIDTH_NARROWBAND)
117 Mediumband = Bandwidth(C.OPUS_BANDWIDTH_MEDIUMBAND)
119 Wideband = Bandwidth(C.OPUS_BANDWIDTH_WIDEBAND)
121 SuperWideband = Bandwidth(C.OPUS_BANDWIDTH_SUPERWIDEBAND)
123 Fullband = Bandwidth(C.OPUS_BANDWIDTH_FULLBAND)
126 var errEncUninitialized = fmt.Errorf("opus encoder uninitialized")
128 // Encoder contains the state of an Opus encoder for libopus.
129 type Encoder struct {
130 p *C.struct_OpusEncoder
132 // Memory for the encoder struct allocated on the Go heap to allow Go GC to
133 // manage it (and obviate need to free())
137 // NewEncoder allocates a new Opus encoder and initializes it with the
138 // appropriate parameters. All related memory is managed by the Go GC.
139 func NewEncoder(sample_rate int, channels int, application Application) (*Encoder, error) {
141 err := enc.Init(sample_rate, channels, application)
148 // Init initializes a pre-allocated opus encoder. Unless the encoder has been
149 // created using NewEncoder, this method must be called exactly once in the
150 // life-time of this object, before calling any other methods.
151 func (enc *Encoder) Init(sample_rate int, channels int, application Application) error {
153 return fmt.Errorf("opus encoder already initialized")
155 if channels != 1 && channels != 2 {
156 return fmt.Errorf("Number of channels must be 1 or 2: %d", channels)
158 size := C.opus_encoder_get_size(C.int(channels))
159 enc.channels = channels
160 enc.mem = make([]byte, size)
161 enc.p = (*C.OpusEncoder)(unsafe.Pointer(&enc.mem[0]))
162 errno := int(C.opus_encoder_init(
164 C.opus_int32(sample_rate),
168 return Error(int(errno))
173 // Encode raw PCM data and store the result in the supplied buffer. On success,
174 // returns the number of bytes used up by the encoded data.
175 func (enc *Encoder) Encode(pcm []int16, data []byte) (int, error) {
177 return 0, errEncUninitialized
180 return 0, fmt.Errorf("opus: no data supplied")
183 return 0, fmt.Errorf("opus: no target buffer")
185 // libopus talks about samples as 1 sample containing multiple channels. So
186 // e.g. 20 samples of 2-channel data is actually 40 raw data points.
187 if len(pcm)%enc.channels != 0 {
188 return 0, fmt.Errorf("opus: input buffer length must be multiple of channels")
190 samples := len(pcm) / enc.channels
191 n := int(C.opus_encode(
193 (*C.opus_int16)(&pcm[0]),
195 (*C.uchar)(&data[0]),
196 C.opus_int32(cap(data))))
203 // Encode raw PCM data and store the result in the supplied buffer. On success,
204 // returns the number of bytes used up by the encoded data.
205 func (enc *Encoder) EncodeFloat32(pcm []float32, data []byte) (int, error) {
207 return 0, errEncUninitialized
210 return 0, fmt.Errorf("opus: no data supplied")
213 return 0, fmt.Errorf("opus: no target buffer")
215 if len(pcm)%enc.channels != 0 {
216 return 0, fmt.Errorf("opus: input buffer length must be multiple of channels")
218 samples := len(pcm) / enc.channels
219 n := int(C.opus_encode_float(
223 (*C.uchar)(&data[0]),
224 C.opus_int32(cap(data))))
231 // SetDTX configures the encoder's use of discontinuous transmission (DTX).
232 func (enc *Encoder) SetDTX(dtx bool) error {
237 res := C.bridge_encoder_set_dtx(enc.p, C.opus_int32(i))
238 if res != C.OPUS_OK {
244 // DTX reports whether this encoder is configured to use discontinuous
245 // transmission (DTX).
246 func (enc *Encoder) DTX() (bool, error) {
248 res := C.bridge_encoder_get_dtx(enc.p, &dtx)
249 if res != C.OPUS_OK {
250 return false, Error(res)
255 // InDTX returns whether the last encoded frame was either a comfort noise update
256 // during DTX or not encoded because of DTX.
257 func (enc *Encoder) InDTX() (bool, error) {
258 var inDTX C.opus_int32
259 res := C.bridge_encoder_get_in_dtx(enc.p, &inDTX)
260 if res != C.OPUS_OK {
261 return false, Error(res)
263 return inDTX != 0, nil
266 // SampleRate returns the encoder sample rate in Hz.
267 func (enc *Encoder) SampleRate() (int, error) {
269 res := C.bridge_encoder_get_sample_rate(enc.p, &sr)
270 if res != C.OPUS_OK {
276 // SetBitrate sets the bitrate of the Encoder
277 func (enc *Encoder) SetBitrate(bitrate int) error {
278 res := C.bridge_encoder_set_bitrate(enc.p, C.opus_int32(bitrate))
279 if res != C.OPUS_OK {
285 // SetBitrateToAuto will allow the encoder to automatically set the bitrate
286 func (enc *Encoder) SetBitrateToAuto() error {
287 res := C.bridge_encoder_set_bitrate(enc.p, C.opus_int32(C.OPUS_AUTO))
288 if res != C.OPUS_OK {
294 // SetBitrateToMax causes the encoder to use as much rate as it can. This can be
295 // useful for controlling the rate by adjusting the output buffer size.
296 func (enc *Encoder) SetBitrateToMax() error {
297 res := C.bridge_encoder_set_bitrate(enc.p, C.opus_int32(C.OPUS_BITRATE_MAX))
298 if res != C.OPUS_OK {
304 // Bitrate returns the bitrate of the Encoder
305 func (enc *Encoder) Bitrate() (int, error) {
306 var bitrate C.opus_int32
307 res := C.bridge_encoder_get_bitrate(enc.p, &bitrate)
308 if res != C.OPUS_OK {
311 return int(bitrate), nil
314 // SetComplexity sets the encoder's computational complexity
315 func (enc *Encoder) SetComplexity(complexity int) error {
316 res := C.bridge_encoder_set_complexity(enc.p, C.opus_int32(complexity))
317 if res != C.OPUS_OK {
323 // Complexity returns the computational complexity used by the encoder
324 func (enc *Encoder) Complexity() (int, error) {
325 var complexity C.opus_int32
326 res := C.bridge_encoder_get_complexity(enc.p, &complexity)
327 if res != C.OPUS_OK {
330 return int(complexity), nil
333 // SetMaxBandwidth configures the maximum bandpass that the encoder will select
335 func (enc *Encoder) SetMaxBandwidth(maxBw Bandwidth) error {
336 res := C.bridge_encoder_set_max_bandwidth(enc.p, C.opus_int32(maxBw))
337 if res != C.OPUS_OK {
343 // MaxBandwidth gets the encoder's configured maximum allowed bandpass.
344 func (enc *Encoder) MaxBandwidth() (Bandwidth, error) {
345 var maxBw C.opus_int32
346 res := C.bridge_encoder_get_max_bandwidth(enc.p, &maxBw)
347 if res != C.OPUS_OK {
350 return Bandwidth(maxBw), nil
353 // SetInBandFEC configures the encoder's use of inband forward error
355 func (enc *Encoder) SetInBandFEC(fec bool) error {
360 res := C.bridge_encoder_set_inband_fec(enc.p, C.opus_int32(i))
361 if res != C.OPUS_OK {
367 // InBandFEC gets the encoder's configured inband forward error correction (FEC)
368 func (enc *Encoder) InBandFEC() (bool, error) {
370 res := C.bridge_encoder_get_inband_fec(enc.p, &fec)
371 if res != C.OPUS_OK {
372 return false, Error(res)
377 // SetPacketLossPerc configures the encoder's expected packet loss percentage.
378 func (enc *Encoder) SetPacketLossPerc(lossPerc int) error {
379 res := C.bridge_encoder_set_packet_loss_perc(enc.p, C.opus_int32(lossPerc))
380 if res != C.OPUS_OK {
386 // PacketLossPerc gets the encoder's configured packet loss percentage.
387 func (enc *Encoder) PacketLossPerc() (int, error) {
388 var lossPerc C.opus_int32
389 res := C.bridge_encoder_get_packet_loss_perc(enc.p, &lossPerc)
390 if res != C.OPUS_OK {
393 return int(lossPerc), nil
396 // Reset resets the codec state to be equivalent to a freshly initialized state.
397 func (enc *Encoder) Reset() error {
398 res := C.bridge_encoder_reset_state(enc.p)
399 if res != C.OPUS_OK {