a5f3ffd5705cbfdd49a24af5b9f967daf7c025f5
[opus.git] / src / opus_encoder.c
1 /* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited
2    Written by Jean-Marc Valin and Koen Vos */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14
15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
19    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <stdarg.h>
35 #include "celt.h"
36 #include "opus_encoder.h"
37 #include "entenc.h"
38 #include "modes.h"
39 #include "SKP_Silk_SDK_API.h"
40
41 OpusEncoder *opus_encoder_create(int Fs, int channels)
42 {
43     int err;
44     char *raw_state;
45         OpusEncoder *st;
46         int ret, silkEncSizeBytes, celtEncSizeBytes;
47
48     /* Create SILK encoder */
49     ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes );
50     if( ret ) {
51         /* Handle error */
52     }
53     celtEncSizeBytes = celt_encoder_get_size(channels);
54     raw_state = calloc(sizeof(OpusEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1);
55     st = (OpusEncoder*)raw_state;
56     st->silk_enc = (void*)(raw_state+sizeof(OpusEncoder));
57     st->celt_enc = (CELTEncoder*)(raw_state+sizeof(OpusEncoder)+silkEncSizeBytes);
58     st->stream_channels = st->channels = channels;
59
60     st->Fs = Fs;
61
62     ret = SKP_Silk_SDK_InitEncoder( st->silk_enc, &st->silk_mode );
63     if( ret ) {
64         /* Handle error */
65     }
66
67     /* default SILK parameters */
68     st->silk_mode.API_sampleRate        = st->Fs;
69     st->silk_mode.nChannels             = channels;
70     st->silk_mode.maxInternalSampleRate = 16000;
71     st->silk_mode.minInternalSampleRate = 8000;
72     st->silk_mode.payloadSize_ms        = 20;
73     st->silk_mode.packetLossPercentage  = 0;
74     st->silk_mode.useInBandFEC          = 0;
75     st->silk_mode.useDTX                = 0;
76     st->silk_mode.complexity            = 10;
77
78     /* Create CELT encoder */
79         /* Initialize CELT encoder */
80         st->celt_enc = celt_encoder_init(st->celt_enc, Fs, channels, &err);
81     celt_encoder_ctl(st->celt_enc, CELT_SET_SIGNALLING(0));
82
83         st->mode = MODE_HYBRID;
84         st->bandwidth = BANDWIDTH_FULLBAND;
85         st->use_vbr = 0;
86         st->bitrate_bps = 32000;
87         st->user_mode = OPUS_MODE_AUTO;
88         st->user_bandwidth = BANDWIDTH_AUTO;
89         st->voice_ratio = 90;
90
91         st->encoder_buffer = st->Fs/100;
92         st->delay_compensation = st->Fs/400;
93         if (st->Fs > 16000)
94                 st->delay_compensation += 10;
95         return st;
96 }
97
98 int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
99                 unsigned char *data, int max_data_bytes)
100 {
101     int i;
102         int ret=0;
103         SKP_int32 nBytes;
104         ec_enc enc;
105         int framerate, period;
106     int silk_internal_bandwidth;
107     int bytes_target;
108     int prefill=0;
109     int start_band = 0;
110     int redundancy = 0;
111     int redundancy_bytes = 0;
112     int celt_to_silk = 0;
113     short pcm_buf[960*2];
114     int nb_compr_bytes;
115     int to_celt = 0;
116     celt_int32 mono_rate;
117
118     if (st->channels == 2)
119     {
120         celt_int32 decision_rate;
121         decision_rate = st->bitrate_bps + st->voice_ratio*st->voice_ratio;
122         if (st->stream_channels == 2)
123             decision_rate += 4000;
124         else
125             decision_rate -= 4000;
126         if (decision_rate>48000)
127             st->stream_channels = 2;
128         else
129             st->stream_channels = 1;
130     } else {
131         st->stream_channels = 1;
132     }
133     /* Equivalent bit-rate for mono */
134     mono_rate = st->bitrate_bps;
135     if (st->stream_channels==2)
136         mono_rate = (mono_rate+10000)/2;
137
138     /* Mode selection */
139     if (st->user_mode==OPUS_MODE_AUTO)
140     {
141         celt_int32 decision_rate;
142         decision_rate = mono_rate - 3*st->voice_ratio*st->voice_ratio;
143         if (st->prev_mode == MODE_CELT_ONLY)
144             decision_rate += 4000;
145         else if (st->prev_mode>0)
146             decision_rate -= 4000;
147         if (decision_rate>24000)
148             st->mode = MODE_CELT_ONLY;
149         else
150             st->mode = MODE_SILK_ONLY;
151     } else if (st->user_mode==OPUS_MODE_VOICE)
152     {
153         st->mode = MODE_SILK_ONLY;
154     } else {/* OPUS_AUDIO_MODE */
155         st->mode = MODE_CELT_ONLY;
156     }
157
158     /* Bandwidth selection */
159     if (st->mode == MODE_CELT_ONLY)
160     {
161         if (mono_rate>35000 || (mono_rate>28000 && st->bandwidth==BANDWIDTH_FULLBAND))
162             st->bandwidth = BANDWIDTH_FULLBAND;
163         else if (mono_rate>28000 || (mono_rate>24000 && st->bandwidth==BANDWIDTH_SUPERWIDEBAND))
164             st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
165         else if (mono_rate>24000 || (mono_rate>18000 && st->bandwidth==BANDWIDTH_WIDEBAND))
166             st->bandwidth = BANDWIDTH_WIDEBAND;
167         else
168             st->bandwidth = BANDWIDTH_NARROWBAND;
169     } else {
170         if (mono_rate>28000 || (mono_rate>24000 && st->bandwidth==BANDWIDTH_FULLBAND))
171             st->bandwidth = BANDWIDTH_FULLBAND;
172         else if (mono_rate>24000 || (mono_rate>18000 && st->bandwidth==BANDWIDTH_SUPERWIDEBAND))
173             st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
174         else if (mono_rate>18000 || (mono_rate>14000 && st->bandwidth==BANDWIDTH_WIDEBAND))
175             st->bandwidth = BANDWIDTH_WIDEBAND;
176         else if (mono_rate>14000 || (mono_rate>11000 && st->bandwidth==BANDWIDTH_MEDIUMBAND))
177             st->bandwidth = BANDWIDTH_MEDIUMBAND;
178         else
179             st->bandwidth = BANDWIDTH_NARROWBAND;
180     }
181
182     if (st->Fs <= 24000 && st->bandwidth > BANDWIDTH_SUPERWIDEBAND)
183         st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
184     if (st->Fs <= 16000 && st->bandwidth > BANDWIDTH_WIDEBAND)
185         st->bandwidth = BANDWIDTH_WIDEBAND;
186     if (st->Fs <= 12000 && st->bandwidth > BANDWIDTH_MEDIUMBAND)
187         st->bandwidth = BANDWIDTH_MEDIUMBAND;
188     if (st->Fs <= 8000 && st->bandwidth > BANDWIDTH_NARROWBAND)
189         st->bandwidth = BANDWIDTH_NARROWBAND;
190
191     if (st->user_bandwidth != BANDWIDTH_AUTO)
192         st->bandwidth = st->user_bandwidth;
193
194     /* Preventing non-sensical configurations */
195     if (frame_size < st->Fs/100 && st->mode != MODE_CELT_ONLY)
196         st->mode = MODE_CELT_ONLY;
197     if (frame_size > st->Fs/50 && st->mode != MODE_SILK_ONLY)
198         st->mode = MODE_SILK_ONLY;
199     if (st->mode == MODE_CELT_ONLY && st->bandwidth == BANDWIDTH_MEDIUMBAND)
200         st->bandwidth = BANDWIDTH_WIDEBAND;
201     if (st->mode == MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND)
202         st->mode = MODE_HYBRID;
203     if (st->mode == MODE_HYBRID && st->bandwidth <= BANDWIDTH_WIDEBAND)
204         st->mode = MODE_SILK_ONLY;
205
206         bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
207
208         data += 1;
209         if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
210         {
211                 SKP_SILK_SDK_EncControlStruct dummy;
212                 SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy);
213                 prefill=1;
214         }
215         if (st->prev_mode >0 &&
216                 ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
217                 || (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
218         {
219             redundancy = 1;
220             celt_to_silk = (st->mode != MODE_CELT_ONLY);
221             if (!celt_to_silk)
222             {
223                 /* Switch to SILK/hybrid if frame size is 10 ms or more*/
224                 if (frame_size >= st->Fs/100)
225                 {
226                         st->mode = st->prev_mode;
227                         to_celt = 1;
228                 } else {
229                         redundancy=0;
230                 }
231             }
232         }
233
234         ec_enc_init(&enc, data, max_data_bytes-1);
235
236         /* SILK processing */
237     if (st->mode != MODE_CELT_ONLY)
238     {
239         st->silk_mode.bitRate = st->bitrate_bps - 8*st->Fs/frame_size;
240         if( st->mode == MODE_HYBRID ) {
241             if( st->bandwidth == BANDWIDTH_SUPERWIDEBAND ) {
242                 if( st->Fs == 100 * frame_size ) {
243                     /* 24 kHz, 10 ms */
244                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3;
245                 } else {
246                     /* 24 kHz, 20 ms */
247                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3;
248                 }
249             } else {
250                 if( st->Fs == 100 * frame_size ) {
251                     /* 48 kHz, 10 ms */
252                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2;
253                 } else {
254                     /* 48 kHz, 20 ms */
255                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2;
256                 }
257             }
258             /* don't let SILK use more than 80% */
259             if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) {
260                 st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5;
261             }
262         }
263
264         st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
265         if (st->bandwidth == BANDWIDTH_NARROWBAND) {
266             st->silk_mode.maxInternalSampleRate = 8000;
267         } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
268             st->silk_mode.maxInternalSampleRate = 12000;
269         } else {
270             SKP_assert( st->mode == MODE_HYBRID || st->bandwidth == BANDWIDTH_WIDEBAND );
271             st->silk_mode.maxInternalSampleRate = 16000;
272         }
273         if( st->mode == MODE_HYBRID ) {
274             /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
275             st->silk_mode.minInternalSampleRate = 16000;
276         } else {
277             st->silk_mode.minInternalSampleRate = 8000;
278         }
279
280         /* Call SILK encoder for the low band */
281         nBytes = max_data_bytes-1;
282         if (prefill)
283         {
284             int zero=0;
285                 SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, st->delay_buffer, st->encoder_buffer, NULL, &zero, 1 );
286         }
287
288         ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 );
289         if( ret ) {
290             fprintf (stderr, "SILK encode error: %d\n", ret);
291             /* Handle error */
292         }
293         if (nBytes==0)
294             return 0;
295
296         /* Extract SILK internal bandwidth for signaling in first byte */
297         if( st->mode == MODE_SILK_ONLY ) {
298             if( st->silk_mode.internalSampleRate == 8000 ) {
299                 silk_internal_bandwidth = BANDWIDTH_NARROWBAND;
300             } else if( st->silk_mode.internalSampleRate == 12000 ) {
301                 silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND;
302             } else if( st->silk_mode.internalSampleRate == 16000 ) {
303                 silk_internal_bandwidth = BANDWIDTH_WIDEBAND;
304             }
305         } else {
306             SKP_assert( st->silk_mode.internalSampleRate == 16000 );
307         }
308     }
309
310     /* CELT processing */
311         {
312             int endband=21;
313
314             switch(st->bandwidth)
315             {
316             case BANDWIDTH_NARROWBAND:
317                 endband = 13;
318                 break;
319             case BANDWIDTH_WIDEBAND:
320                 endband = 17;
321                 break;
322             case BANDWIDTH_SUPERWIDEBAND:
323                 endband = 19;
324                 break;
325             case BANDWIDTH_FULLBAND:
326                 endband = 21;
327                 break;
328             }
329             celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband));
330             celt_encoder_ctl(st->celt_enc, CELT_SET_CHANNELS(st->stream_channels));
331         }
332         if (st->mode != MODE_SILK_ONLY)
333         {
334         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
335         celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000));
336         if (st->prev_mode == MODE_SILK_ONLY)
337         {
338                 unsigned char dummy[10];
339                 celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
340                 celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
341                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
342                 /* FIXME: This wastes CPU a bit compared to just prefilling the buffer */
343                 celt_encode(st->celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10);
344         } else {
345                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2));
346         }
347
348         if (st->mode == MODE_HYBRID)
349         {
350             int len;
351
352             len = (ec_tell(&enc)+7)>>3;
353             if( st->use_vbr ) {
354                 nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
355             } else {
356                 /* check if SILK used up too much */
357                 nb_compr_bytes = len > bytes_target ? len : bytes_target;
358             }
359         } else {
360             if (st->use_vbr)
361             {
362                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
363                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint));
364                 celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps));
365                 nb_compr_bytes = max_data_bytes-1;
366             } else {
367                 nb_compr_bytes = bytes_target;
368             }
369         }
370
371         ec_enc_shrink(&enc, nb_compr_bytes);
372         } else {
373             nb_compr_bytes = 0;
374         }
375
376     for (i=0;i<IMIN(frame_size, st->delay_compensation)*st->channels;i++)
377         pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation)*st->channels+i];
378     for (;i<frame_size*st->channels;i++)
379         pcm_buf[i] = pcm[i-st->delay_compensation*st->channels];
380     if (st->mode != MODE_CELT_ONLY)
381     {
382         /* Check if we have a redundant 0-8 kHz band */
383         ec_enc_bit_logp(&enc, redundancy, 12);
384         if (redundancy)
385         {
386             redundancy_bytes = st->stream_channels*st->bitrate_bps/1600;
387             ec_enc_bit_logp(&enc, celt_to_silk, 1);
388             if (st->mode == MODE_HYBRID)
389                 ec_enc_uint(&enc, redundancy_bytes-2, 256);
390         }
391         start_band = 17;
392     }
393
394     if (st->mode == MODE_SILK_ONLY)
395     {
396         ret = (ec_tell(&enc)+7)>>3;
397         ec_enc_done(&enc);
398         nb_compr_bytes = ret;
399     }
400
401     /* 5 ms redundant frame for CELT->SILK */
402     if (redundancy && celt_to_silk)
403     {
404         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
405         /* FIXME: That's OK for now, but we need to set the flags properly */
406         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
407         celt_encode(st->celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
408         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
409     }
410
411     celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band));
412
413     if (st->mode != MODE_SILK_ONLY)
414         {
415             /* Encode high band with CELT */
416             ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
417         }
418
419     /* 5 ms redundant frame for SILK->CELT */
420     if (redundancy && !celt_to_silk)
421     {
422         int N2, N4;
423         N2 = st->Fs/200;
424         N4 = st->Fs/400;
425
426         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
427         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
428         celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
429
430         /* FIXME: Do proper prefilling here */
431         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
432
433         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes);
434     }
435
436
437     if (frame_size>st->encoder_buffer)
438     {
439         for (i=0;i<st->encoder_buffer*st->channels;i++)
440                 st->delay_buffer[i] = pcm[(frame_size-st->encoder_buffer)*st->channels+i];
441     } else {
442         int tmp = st->encoder_buffer-frame_size;
443         for (i=0;i<tmp*st->channels;i++)
444                 st->delay_buffer[i] = st->delay_buffer[i+frame_size*st->channels];
445         for (i=0;i<frame_size*st->channels;i++)
446                 st->delay_buffer[tmp*st->channels+i] = pcm[i];
447     }
448
449         /* Signalling the mode in the first byte */
450         data--;
451         framerate = st->Fs/frame_size;
452         period = 0;
453         while (framerate < 400)
454         {
455             framerate <<= 1;
456             period++;
457         }
458     if (st->mode == MODE_SILK_ONLY)
459     {
460         data[0] = (silk_internal_bandwidth-BANDWIDTH_NARROWBAND)<<5;
461         data[0] |= (period-2)<<3;
462     } else if (st->mode == MODE_CELT_ONLY)
463     {
464         int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
465         if (tmp < 0)
466             tmp = 0;
467         data[0] = 0x80;
468         data[0] |= tmp << 5;
469         data[0] |= period<<3;
470     } else /* Hybrid */
471     {
472         data[0] = 0x60;
473         data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
474         data[0] |= (period-2)<<3;
475     }
476     data[0] |= (st->stream_channels==2)<<2;
477     /*printf ("%x\n", (int)data[0]);*/
478
479 #if OPUS_TEST_RANGE_CODER_STATE
480     st->rangeFinal = enc.rng;
481 #endif
482     if (to_celt)
483         st->prev_mode = MODE_CELT_ONLY;
484     else
485         st->prev_mode = st->mode;
486     return ret+1+redundancy_bytes;
487 }
488
489 int opus_encoder_ctl(OpusEncoder *st, int request, ...)
490 {
491     va_list ap;
492
493     va_start(ap, request);
494
495     switch (request)
496     {
497         case OPUS_SET_MODE_REQUEST:
498         {
499             int value = va_arg(ap, int);
500             st->user_mode = value;
501         }
502         break;
503         case OPUS_GET_MODE_REQUEST:
504         {
505             int *value = va_arg(ap, int*);
506             *value = st->mode;
507         }
508         break;
509         case OPUS_SET_BITRATE_REQUEST:
510         {
511             int value = va_arg(ap, int);
512             st->bitrate_bps = value;
513         }
514         break;
515         case OPUS_GET_BITRATE_REQUEST:
516         {
517             int *value = va_arg(ap, int*);
518             *value = st->bitrate_bps;
519         }
520         break;
521         case OPUS_SET_BANDWIDTH_REQUEST:
522         {
523             int value = va_arg(ap, int);
524             if (value < BANDWIDTH_AUTO || value > BANDWIDTH_FULLBAND)
525                 return OPUS_BAD_ARG;
526             st->user_bandwidth = value;
527             if (st->user_bandwidth == BANDWIDTH_NARROWBAND) {
528                 st->silk_mode.maxInternalSampleRate = 8000;
529             } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
530                 st->silk_mode.maxInternalSampleRate = 12000;
531             } else {
532                 st->silk_mode.maxInternalSampleRate = 16000;
533             }
534         }
535         break;
536         case OPUS_GET_BANDWIDTH_REQUEST:
537         {
538             int *value = va_arg(ap, int*);
539             *value = st->bandwidth;
540         }
541         break;
542         case OPUS_SET_DTX_FLAG_REQUEST:
543         {
544             int value = va_arg(ap, int);
545             st->silk_mode.useDTX = value;
546         }
547         break;
548         case OPUS_GET_DTX_FLAG_REQUEST:
549         {
550             int *value = va_arg(ap, int*);
551             *value = st->silk_mode.useDTX;
552         }
553         break;
554         case OPUS_SET_COMPLEXITY_REQUEST:
555         {
556             int value = va_arg(ap, int);
557             st->silk_mode.complexity = value;
558             celt_encoder_ctl(st->celt_enc, CELT_SET_COMPLEXITY(value));
559         }
560         break;
561         case OPUS_GET_COMPLEXITY_REQUEST:
562         {
563             int *value = va_arg(ap, int*);
564             *value = st->silk_mode.complexity;
565         }
566         break;
567         case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
568         {
569             int value = va_arg(ap, int);
570             st->silk_mode.useInBandFEC = value;
571         }
572         break;
573         case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
574         {
575             int *value = va_arg(ap, int*);
576             *value = st->silk_mode.useInBandFEC;
577         }
578         break;
579         case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
580         {
581             int value = va_arg(ap, int);
582             if (value < 0 || value > 100)
583                 return OPUS_BAD_ARG;
584             st->silk_mode.packetLossPercentage = value;
585             celt_encoder_ctl(st->celt_enc, CELT_SET_LOSS_PERC(value));
586         }
587         break;
588         case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
589         {
590             int *value = va_arg(ap, int*);
591             *value = st->silk_mode.packetLossPercentage;
592         }
593         break;
594         case OPUS_SET_VBR_FLAG_REQUEST:
595         {
596             int value = va_arg(ap, int);
597             st->use_vbr = value;
598             st->silk_mode.useCBR = 1-value;
599         }
600         break;
601         case OPUS_GET_VBR_FLAG_REQUEST:
602         {
603             int *value = va_arg(ap, int*);
604             *value = st->use_vbr;
605         }
606         break;
607         case OPUS_SET_VOICE_RATIO_REQUEST:
608         {
609             int value = va_arg(ap, int);
610             if (value>100 || value<0)
611                 goto bad_arg;
612             st->voice_ratio = value;
613         }
614         break;
615         case OPUS_GET_VOICE_RATIO_REQUEST:
616         {
617             int *value = va_arg(ap, int*);
618             *value = st->voice_ratio;
619         }
620         break;
621         case OPUS_SET_VBR_CONSTRAINT_REQUEST:
622         {
623             int value = va_arg(ap, int);
624             st->vbr_constraint = value;
625         }
626         break;
627         case OPUS_GET_VBR_CONSTRAINT_REQUEST:
628         {
629             int *value = va_arg(ap, int*);
630             *value = st->vbr_constraint;
631         }
632         break;
633         default:
634             fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
635             break;
636     }
637     va_end(ap);
638     return OPUS_OK;
639 bad_arg:
640     va_end(ap);
641     return OPUS_BAD_ARG;
642 }
643
644 void opus_encoder_destroy(OpusEncoder *st)
645 {
646         free(st);
647 }
648
649 #if OPUS_TEST_RANGE_CODER_STATE
650 int opus_encoder_get_final_range(OpusEncoder *st)
651 {
652     return st->rangeFinal;
653 }
654 #endif