]> Sergey Matveev's repositories - go-opus.git/blob - encoder.go
Build libopus statically
[go-opus.git] / encoder.go
1 // Copyright © Go Opus Authors (see AUTHORS file)
2 //
3 // License for use of this code is detailed in the LICENSE file
4
5 package opus
6
7 import (
8         "fmt"
9         "unsafe"
10 )
11
12 /*
13 #cgo pkg-config: --static opus
14 #cgo LDFLAGS: -static
15 #include <opus.h>
16
17 int
18 bridge_encoder_set_dtx(OpusEncoder *st, opus_int32 use_dtx)
19 {
20         return opus_encoder_ctl(st, OPUS_SET_DTX(use_dtx));
21 }
22
23 int
24 bridge_encoder_get_dtx(OpusEncoder *st, opus_int32 *dtx)
25 {
26         return opus_encoder_ctl(st, OPUS_GET_DTX(dtx));
27 }
28
29 int
30 bridge_encoder_get_in_dtx(OpusEncoder *st, opus_int32 *in_dtx)
31 {
32         return opus_encoder_ctl(st, OPUS_GET_IN_DTX(in_dtx));
33 }
34
35 int
36 bridge_encoder_get_sample_rate(OpusEncoder *st, opus_int32 *sample_rate)
37 {
38         return opus_encoder_ctl(st, OPUS_GET_SAMPLE_RATE(sample_rate));
39 }
40
41
42 int
43 bridge_encoder_set_bitrate(OpusEncoder *st, opus_int32 bitrate)
44 {
45         return opus_encoder_ctl(st, OPUS_SET_BITRATE(bitrate));
46 }
47
48 int
49 bridge_encoder_get_bitrate(OpusEncoder *st, opus_int32 *bitrate)
50 {
51         return opus_encoder_ctl(st, OPUS_GET_BITRATE(bitrate));
52 }
53
54 int
55 bridge_encoder_set_complexity(OpusEncoder *st, opus_int32 complexity)
56 {
57         return opus_encoder_ctl(st, OPUS_SET_COMPLEXITY(complexity));
58 }
59
60 int
61 bridge_encoder_get_complexity(OpusEncoder *st, opus_int32 *complexity)
62 {
63         return opus_encoder_ctl(st, OPUS_GET_COMPLEXITY(complexity));
64 }
65
66 int
67 bridge_encoder_set_max_bandwidth(OpusEncoder *st, opus_int32 max_bw)
68 {
69         return opus_encoder_ctl(st, OPUS_SET_MAX_BANDWIDTH(max_bw));
70 }
71
72 int
73 bridge_encoder_get_max_bandwidth(OpusEncoder *st, opus_int32 *max_bw)
74 {
75         return opus_encoder_ctl(st, OPUS_GET_MAX_BANDWIDTH(max_bw));
76 }
77
78 int
79 bridge_encoder_set_inband_fec(OpusEncoder *st, opus_int32 fec)
80 {
81         return opus_encoder_ctl(st, OPUS_SET_INBAND_FEC(fec));
82 }
83
84 int
85 bridge_encoder_get_inband_fec(OpusEncoder *st, opus_int32 *fec)
86 {
87         return opus_encoder_ctl(st, OPUS_GET_INBAND_FEC(fec));
88 }
89
90 int
91 bridge_encoder_set_packet_loss_perc(OpusEncoder *st, opus_int32 loss_perc)
92 {
93         return opus_encoder_ctl(st, OPUS_SET_PACKET_LOSS_PERC(loss_perc));
94 }
95
96 int
97 bridge_encoder_get_packet_loss_perc(OpusEncoder *st, opus_int32 *loss_perc)
98 {
99         return opus_encoder_ctl(st, OPUS_GET_PACKET_LOSS_PERC(loss_perc));
100 }
101
102 int
103 bridge_encoder_reset_state(OpusEncoder *st)
104 {
105         return opus_encoder_ctl(st, OPUS_RESET_STATE);
106 }
107
108 */
109 import "C"
110
111 type Bandwidth int
112
113 const (
114         // 4 kHz passband
115         Narrowband = Bandwidth(C.OPUS_BANDWIDTH_NARROWBAND)
116         // 6 kHz passband
117         Mediumband = Bandwidth(C.OPUS_BANDWIDTH_MEDIUMBAND)
118         // 8 kHz passband
119         Wideband = Bandwidth(C.OPUS_BANDWIDTH_WIDEBAND)
120         // 12 kHz passband
121         SuperWideband = Bandwidth(C.OPUS_BANDWIDTH_SUPERWIDEBAND)
122         // 20 kHz passband
123         Fullband = Bandwidth(C.OPUS_BANDWIDTH_FULLBAND)
124 )
125
126 var errEncUninitialized = fmt.Errorf("opus encoder uninitialized")
127
128 // Encoder contains the state of an Opus encoder for libopus.
129 type Encoder struct {
130         p        *C.struct_OpusEncoder
131         channels int
132         // Memory for the encoder struct allocated on the Go heap to allow Go GC to
133         // manage it (and obviate need to free())
134         mem []byte
135 }
136
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) {
140         var enc Encoder
141         err := enc.Init(sample_rate, channels, application)
142         if err != nil {
143                 return nil, err
144         }
145         return &enc, nil
146 }
147
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 {
152         if enc.p != nil {
153                 return fmt.Errorf("opus encoder already initialized")
154         }
155         if channels != 1 && channels != 2 {
156                 return fmt.Errorf("Number of channels must be 1 or 2: %d", channels)
157         }
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(
163                 enc.p,
164                 C.opus_int32(sample_rate),
165                 C.int(channels),
166                 C.int(application)))
167         if errno != 0 {
168                 return Error(int(errno))
169         }
170         return nil
171 }
172
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) {
176         if enc.p == nil {
177                 return 0, errEncUninitialized
178         }
179         if len(pcm) == 0 {
180                 return 0, fmt.Errorf("opus: no data supplied")
181         }
182         if len(data) == 0 {
183                 return 0, fmt.Errorf("opus: no target buffer")
184         }
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")
189         }
190         samples := len(pcm) / enc.channels
191         n := int(C.opus_encode(
192                 enc.p,
193                 (*C.opus_int16)(&pcm[0]),
194                 C.int(samples),
195                 (*C.uchar)(&data[0]),
196                 C.opus_int32(cap(data))))
197         if n < 0 {
198                 return 0, Error(n)
199         }
200         return n, nil
201 }
202
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) {
206         if enc.p == nil {
207                 return 0, errEncUninitialized
208         }
209         if len(pcm) == 0 {
210                 return 0, fmt.Errorf("opus: no data supplied")
211         }
212         if len(data) == 0 {
213                 return 0, fmt.Errorf("opus: no target buffer")
214         }
215         if len(pcm)%enc.channels != 0 {
216                 return 0, fmt.Errorf("opus: input buffer length must be multiple of channels")
217         }
218         samples := len(pcm) / enc.channels
219         n := int(C.opus_encode_float(
220                 enc.p,
221                 (*C.float)(&pcm[0]),
222                 C.int(samples),
223                 (*C.uchar)(&data[0]),
224                 C.opus_int32(cap(data))))
225         if n < 0 {
226                 return 0, Error(n)
227         }
228         return n, nil
229 }
230
231 // SetDTX configures the encoder's use of discontinuous transmission (DTX).
232 func (enc *Encoder) SetDTX(dtx bool) error {
233         i := 0
234         if dtx {
235                 i = 1
236         }
237         res := C.bridge_encoder_set_dtx(enc.p, C.opus_int32(i))
238         if res != C.OPUS_OK {
239                 return Error(res)
240         }
241         return nil
242 }
243
244 // DTX reports whether this encoder is configured to use discontinuous
245 // transmission (DTX).
246 func (enc *Encoder) DTX() (bool, error) {
247         var dtx C.opus_int32
248         res := C.bridge_encoder_get_dtx(enc.p, &dtx)
249         if res != C.OPUS_OK {
250                 return false, Error(res)
251         }
252         return dtx != 0, nil
253 }
254
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)
262         }
263         return inDTX != 0, nil
264 }
265
266 // SampleRate returns the encoder sample rate in Hz.
267 func (enc *Encoder) SampleRate() (int, error) {
268         var sr C.opus_int32
269         res := C.bridge_encoder_get_sample_rate(enc.p, &sr)
270         if res != C.OPUS_OK {
271                 return 0, Error(res)
272         }
273         return int(sr), nil
274 }
275
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 {
280                 return Error(res)
281         }
282         return nil
283 }
284
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 {
289                 return Error(res)
290         }
291         return nil
292 }
293
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 {
299                 return Error(res)
300         }
301         return nil
302 }
303
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 {
309                 return 0, Error(res)
310         }
311         return int(bitrate), nil
312 }
313
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 {
318                 return Error(res)
319         }
320         return nil
321 }
322
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 {
328                 return 0, Error(res)
329         }
330         return int(complexity), nil
331 }
332
333 // SetMaxBandwidth configures the maximum bandpass that the encoder will select
334 // automatically
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 {
338                 return Error(res)
339         }
340         return nil
341 }
342
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 {
348                 return 0, Error(res)
349         }
350         return Bandwidth(maxBw), nil
351 }
352
353 // SetInBandFEC configures the encoder's use of inband forward error
354 // correction (FEC)
355 func (enc *Encoder) SetInBandFEC(fec bool) error {
356         i := 0
357         if fec {
358                 i = 1
359         }
360         res := C.bridge_encoder_set_inband_fec(enc.p, C.opus_int32(i))
361         if res != C.OPUS_OK {
362                 return Error(res)
363         }
364         return nil
365 }
366
367 // InBandFEC gets the encoder's configured inband forward error correction (FEC)
368 func (enc *Encoder) InBandFEC() (bool, error) {
369         var fec C.opus_int32
370         res := C.bridge_encoder_get_inband_fec(enc.p, &fec)
371         if res != C.OPUS_OK {
372                 return false, Error(res)
373         }
374         return fec != 0, nil
375 }
376
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 {
381                 return Error(res)
382         }
383         return nil
384 }
385
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 {
391                 return 0, Error(res)
392         }
393         return int(lossPerc), nil
394 }
395
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 {
400                 return Error(res)
401         }
402         return nil
403 }