b0a22f9f8da4c8b3c2df640131a7cbab2bfae39c
[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.maxInternalSampleRate = 16000;
70     st->silk_mode.minInternalSampleRate = 8000;
71     st->silk_mode.payloadSize_ms        = 20;
72     st->silk_mode.packetLossPercentage  = 0;
73     st->silk_mode.useInBandFEC          = 0;
74     st->silk_mode.useDTX                = 0;
75     st->silk_mode.complexity            = 10;
76
77     /* Create CELT encoder */
78         /* Initialize CELT encoder */
79         st->celt_enc = celt_encoder_init(st->celt_enc, Fs, channels, &err);
80     celt_encoder_ctl(st->celt_enc, CELT_SET_SIGNALLING(0));
81
82         st->mode = MODE_HYBRID;
83         st->bandwidth = BANDWIDTH_FULLBAND;
84         st->use_vbr = 0;
85         st->bitrate_bps = 32000;
86         st->user_mode = OPUS_MODE_AUTO;
87         st->user_bandwidth = BANDWIDTH_AUTO;
88         st->voice_ratio = 90;
89
90         st->encoder_buffer = st->Fs/100;
91         st->delay_compensation = st->Fs/400;
92         if (st->Fs > 16000)
93                 st->delay_compensation += 10;
94         return st;
95 }
96
97 int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
98                 unsigned char *data, int max_data_bytes)
99 {
100     int i;
101         int ret=0;
102         SKP_int32 nBytes;
103         ec_enc enc;
104         int framerate, period;
105     int silk_internal_bandwidth;
106     int bytes_target;
107     int prefill=0;
108     int start_band = 0;
109     int redundancy = 0;
110     int redundancy_bytes = 0;
111     int celt_to_silk = 0;
112     short pcm_buf[960*2];
113     int nb_compr_bytes;
114     int to_celt = 0;
115     celt_int32 mono_rate;
116
117     if (st->channels == 2)
118     {
119         celt_int32 decision_rate;
120         decision_rate = st->bitrate_bps + st->voice_ratio*st->voice_ratio;
121         if (st->stream_channels == 2)
122             decision_rate += 4000;
123         else
124             decision_rate -= 4000;
125         if (decision_rate>48000)
126             st->stream_channels = 2;
127         else
128             st->stream_channels = 1;
129     } else {
130         st->stream_channels = 1;
131     }
132     /* Equivalent bit-rate for mono */
133     mono_rate = st->bitrate_bps;
134     if (st->stream_channels==2)
135         mono_rate = (mono_rate+10000)/2;
136
137     /* Mode selection */
138     if (st->user_mode==OPUS_MODE_AUTO)
139     {
140         celt_int32 decision_rate;
141         decision_rate = mono_rate - 3*st->voice_ratio*st->voice_ratio;
142         if (st->prev_mode == MODE_CELT_ONLY)
143             decision_rate += 4000;
144         else if (st->prev_mode>0)
145             decision_rate -= 4000;
146         if (decision_rate>24000)
147             st->mode = MODE_CELT_ONLY;
148         else
149             st->mode = MODE_SILK_ONLY;
150     } else if (st->user_mode==OPUS_MODE_VOICE)
151     {
152         st->mode = MODE_SILK_ONLY;
153     } else {/* OPUS_AUDIO_MODE */
154         st->mode = MODE_CELT_ONLY;
155     }
156
157     /* FIXME: Remove this once SILK supports stereo */
158     if (st->channels == 2)
159         st->mode = MODE_CELT_ONLY;
160
161     /* Bandwidth selection */
162     if (st->mode == MODE_CELT_ONLY)
163     {
164         if (mono_rate>35000 || (mono_rate>28000 && st->bandwidth==BANDWIDTH_FULLBAND))
165             st->bandwidth = BANDWIDTH_FULLBAND;
166         else if (mono_rate>28000 || (mono_rate>24000 && st->bandwidth==BANDWIDTH_SUPERWIDEBAND))
167             st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
168         else if (mono_rate>24000 || (mono_rate>18000 && st->bandwidth==BANDWIDTH_WIDEBAND))
169             st->bandwidth = BANDWIDTH_WIDEBAND;
170         else
171             st->bandwidth = BANDWIDTH_NARROWBAND;
172     } else {
173         if (mono_rate>28000 || (mono_rate>24000 && st->bandwidth==BANDWIDTH_FULLBAND))
174             st->bandwidth = BANDWIDTH_FULLBAND;
175         else if (mono_rate>24000 || (mono_rate>18000 && st->bandwidth==BANDWIDTH_SUPERWIDEBAND))
176             st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
177         else if (mono_rate>18000 || (mono_rate>14000 && st->bandwidth==BANDWIDTH_WIDEBAND))
178             st->bandwidth = BANDWIDTH_WIDEBAND;
179         else if (mono_rate>14000 || (mono_rate>11000 && st->bandwidth==BANDWIDTH_MEDIUMBAND))
180             st->bandwidth = BANDWIDTH_MEDIUMBAND;
181         else
182             st->bandwidth = BANDWIDTH_NARROWBAND;
183     }
184
185     if (st->Fs <= 24000 && st->bandwidth > BANDWIDTH_SUPERWIDEBAND)
186         st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
187     if (st->Fs <= 16000 && st->bandwidth > BANDWIDTH_WIDEBAND)
188         st->bandwidth = BANDWIDTH_WIDEBAND;
189     if (st->Fs <= 12000 && st->bandwidth > BANDWIDTH_MEDIUMBAND)
190         st->bandwidth = BANDWIDTH_MEDIUMBAND;
191     if (st->Fs <= 8000 && st->bandwidth > BANDWIDTH_NARROWBAND)
192         st->bandwidth = BANDWIDTH_NARROWBAND;
193
194     if (st->user_bandwidth != BANDWIDTH_AUTO)
195         st->bandwidth = st->user_bandwidth;
196
197     /* Preventing non-sensical configurations */
198     if (frame_size < st->Fs/100 && st->mode != MODE_CELT_ONLY)
199         st->mode = MODE_CELT_ONLY;
200     if (frame_size > st->Fs/50 && st->mode != MODE_SILK_ONLY)
201         st->mode = MODE_SILK_ONLY;
202     if (st->mode == MODE_CELT_ONLY && st->bandwidth == BANDWIDTH_MEDIUMBAND)
203         st->bandwidth = BANDWIDTH_WIDEBAND;
204     if (st->mode == MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND)
205         st->mode = MODE_HYBRID;
206     if (st->mode == MODE_HYBRID && st->bandwidth <= BANDWIDTH_WIDEBAND)
207         st->mode = MODE_SILK_ONLY;
208
209         bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
210
211         data += 1;
212         if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
213         {
214                 SKP_SILK_SDK_EncControlStruct dummy;
215                 SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy);
216                 prefill=1;
217         }
218         if (st->prev_mode >0 &&
219                 ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
220                 || (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
221         {
222             redundancy = 1;
223             celt_to_silk = (st->mode != MODE_CELT_ONLY);
224             if (!celt_to_silk)
225             {
226                 /* Switch to SILK/hybrid if frame size is 10 ms or more*/
227                 if (frame_size >= st->Fs/100)
228                 {
229                         st->mode = st->prev_mode;
230                         to_celt = 1;
231                 } else {
232                         redundancy=0;
233                 }
234             }
235         }
236
237         ec_enc_init(&enc, data, max_data_bytes-1);
238
239         /* SILK processing */
240     if (st->mode != MODE_CELT_ONLY)
241     {
242         st->silk_mode.bitRate = st->bitrate_bps - 8*st->Fs/frame_size;
243         if( st->mode == MODE_HYBRID ) {
244             if( st->bandwidth == BANDWIDTH_SUPERWIDEBAND ) {
245                 if( st->Fs == 100 * frame_size ) {
246                     /* 24 kHz, 10 ms */
247                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3;
248                 } else {
249                     /* 24 kHz, 20 ms */
250                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3;
251                 }
252             } else {
253                 if( st->Fs == 100 * frame_size ) {
254                     /* 48 kHz, 10 ms */
255                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2;
256                 } else {
257                     /* 48 kHz, 20 ms */
258                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2;
259                 }
260             }
261             /* don't let SILK use more than 80% */
262             if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) {
263                 st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5;
264             }
265         }
266
267         st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
268         if (st->bandwidth == BANDWIDTH_NARROWBAND) {
269             st->silk_mode.maxInternalSampleRate = 8000;
270         } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
271             st->silk_mode.maxInternalSampleRate = 12000;
272         } else {
273             SKP_assert( st->mode == MODE_HYBRID || st->bandwidth == BANDWIDTH_WIDEBAND );
274             st->silk_mode.maxInternalSampleRate = 16000;
275         }
276         if( st->mode == MODE_HYBRID ) {
277             /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
278             st->silk_mode.minInternalSampleRate = 16000;
279         } else {
280             st->silk_mode.minInternalSampleRate = 8000;
281         }
282
283         /* Call SILK encoder for the low band */
284         nBytes = max_data_bytes-1;
285         if (prefill)
286         {
287             int zero=0;
288                 SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, st->delay_buffer, st->encoder_buffer, NULL, &zero, 1 );
289         }
290
291         ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 );
292         if( ret ) {
293             fprintf (stderr, "SILK encode error: %d\n", ret);
294             /* Handle error */
295         }
296         if (nBytes==0)
297             return 0;
298
299         /* Extract SILK internal bandwidth for signaling in first byte */
300         if( st->mode == MODE_SILK_ONLY ) {
301             if( st->silk_mode.internalSampleRate == 8000 ) {
302                 silk_internal_bandwidth = BANDWIDTH_NARROWBAND;
303             } else if( st->silk_mode.internalSampleRate == 12000 ) {
304                 silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND;
305             } else if( st->silk_mode.internalSampleRate == 16000 ) {
306                 silk_internal_bandwidth = BANDWIDTH_WIDEBAND;
307             }
308         } else {
309             SKP_assert( st->silk_mode.internalSampleRate == 16000 );
310         }
311     }
312
313     /* CELT processing */
314         {
315             int endband=21;
316
317             switch(st->bandwidth)
318             {
319             case BANDWIDTH_NARROWBAND:
320                 endband = 13;
321                 break;
322             case BANDWIDTH_WIDEBAND:
323                 endband = 17;
324                 break;
325             case BANDWIDTH_SUPERWIDEBAND:
326                 endband = 19;
327                 break;
328             case BANDWIDTH_FULLBAND:
329                 endband = 21;
330                 break;
331             }
332             celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband));
333             celt_encoder_ctl(st->celt_enc, CELT_SET_CHANNELS(st->stream_channels));
334         }
335         if (st->mode != MODE_SILK_ONLY)
336         {
337         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
338         celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000));
339         if (st->prev_mode == MODE_SILK_ONLY)
340         {
341                 unsigned char dummy[10];
342                 celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
343                 celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
344                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
345                 /* FIXME: This wastes CPU a bit compared to just prefilling the buffer */
346                 celt_encode(st->celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10);
347         } else {
348                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2));
349         }
350
351         if (st->mode == MODE_HYBRID)
352         {
353             int len;
354
355             len = (ec_tell(&enc)+7)>>3;
356             if( st->use_vbr ) {
357                 nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
358             } else {
359                 /* check if SILK used up too much */
360                 nb_compr_bytes = len > bytes_target ? len : bytes_target;
361             }
362         } else {
363             if (st->use_vbr)
364             {
365                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
366                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint));
367                 celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps));
368                 nb_compr_bytes = max_data_bytes-1;
369             } else {
370                 nb_compr_bytes = bytes_target;
371             }
372         }
373
374
375         ec_enc_shrink(&enc, nb_compr_bytes);
376         } else {
377             nb_compr_bytes = 0;
378         }
379
380     for (i=0;i<IMIN(frame_size, st->delay_compensation)*st->channels;i++)
381         pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation)*st->channels+i];
382     for (;i<frame_size*st->channels;i++)
383         pcm_buf[i] = pcm[i-st->delay_compensation*st->channels];
384     if (st->mode != MODE_CELT_ONLY)
385     {
386         /* Check if we have a redundant 0-8 kHz band */
387         ec_enc_bit_logp(&enc, redundancy, 12);
388         if (redundancy)
389         {
390             redundancy_bytes = 40;
391             ec_enc_bit_logp(&enc, celt_to_silk, 1);
392             if (st->mode == MODE_HYBRID)
393                 ec_enc_uint(&enc, redundancy_bytes-2, 256);
394         }
395         start_band = 17;
396     }
397
398     if (st->mode == MODE_SILK_ONLY)
399     {
400         ret = (ec_tell(&enc)+7)>>3;
401         ec_enc_done(&enc);
402         nb_compr_bytes = ret;
403     }
404
405     /* 5 ms redundant frame for CELT->SILK */
406     if (redundancy && celt_to_silk)
407     {
408         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
409         /* FIXME: This is wrong -- we need to set the flags properly */
410         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
411         /* FIXME: Make sure not to overflow here */
412         celt_encode(st->celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
413         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
414     }
415
416     celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band));
417
418     if (st->mode != MODE_SILK_ONLY)
419         {
420             /* Encode high band with CELT */
421             ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
422         }
423
424     /* 5 ms redundant frame for SILK->CELT */
425     if (redundancy && !celt_to_silk)
426     {
427         int N2, N4;
428         N2 = st->Fs/200;
429         N4 = st->Fs/400;
430
431         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
432         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
433         celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
434
435         /* FIXME: Do proper prefilling here */
436         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
437
438         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes);
439     }
440
441
442     if (frame_size>st->encoder_buffer)
443     {
444         for (i=0;i<st->encoder_buffer*st->channels;i++)
445                 st->delay_buffer[i] = pcm[(frame_size-st->encoder_buffer)*st->channels+i];
446     } else {
447         int tmp = st->encoder_buffer-frame_size;
448         for (i=0;i<tmp*st->channels;i++)
449                 st->delay_buffer[i] = st->delay_buffer[i+frame_size*st->channels];
450         for (i=0;i<frame_size*st->channels;i++)
451                 st->delay_buffer[tmp*st->channels+i] = pcm[i];
452     }
453
454         /* Signalling the mode in the first byte */
455         data--;
456         framerate = st->Fs/frame_size;
457         period = 0;
458         while (framerate < 400)
459         {
460             framerate <<= 1;
461             period++;
462         }
463     if (st->mode == MODE_SILK_ONLY)
464     {
465         data[0] = (silk_internal_bandwidth-BANDWIDTH_NARROWBAND)<<5;
466         data[0] |= (period-2)<<3;
467     } else if (st->mode == MODE_CELT_ONLY)
468     {
469         int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
470         if (tmp < 0)
471             tmp = 0;
472         data[0] = 0x80;
473         data[0] |= tmp << 5;
474         data[0] |= period<<3;
475     } else /* Hybrid */
476     {
477         data[0] = 0x60;
478         data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
479         data[0] |= (period-2)<<3;
480     }
481     data[0] |= (st->stream_channels==2)<<2;
482     /*printf ("%x\n", (int)data[0]);*/
483
484 #if OPUS_TEST_RANGE_CODER_STATE
485     st->rangeFinal = enc.rng;
486 #endif
487     if (to_celt)
488         st->prev_mode = MODE_CELT_ONLY;
489     else
490         st->prev_mode = st->mode;
491     return ret+1+redundancy_bytes;
492 }
493
494 int opus_encoder_ctl(OpusEncoder *st, int request, ...)
495 {
496     va_list ap;
497
498     va_start(ap, request);
499
500     switch (request)
501     {
502         case OPUS_SET_MODE_REQUEST:
503         {
504             int value = va_arg(ap, int);
505             st->user_mode = value;
506         }
507         break;
508         case OPUS_GET_MODE_REQUEST:
509         {
510             int *value = va_arg(ap, int*);
511             *value = st->mode;
512         }
513         break;
514         case OPUS_SET_BITRATE_REQUEST:
515         {
516             int value = va_arg(ap, int);
517             st->bitrate_bps = value;
518         }
519         break;
520         case OPUS_GET_BITRATE_REQUEST:
521         {
522             int *value = va_arg(ap, int*);
523             *value = st->bitrate_bps;
524         }
525         break;
526         case OPUS_SET_BANDWIDTH_REQUEST:
527         {
528             int value = va_arg(ap, int);
529             if (value < BANDWIDTH_AUTO || value > BANDWIDTH_FULLBAND)
530                 return OPUS_BAD_ARG;
531             st->user_bandwidth = value;
532             if (st->user_bandwidth == BANDWIDTH_NARROWBAND) {
533                 st->silk_mode.maxInternalSampleRate = 8000;
534             } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
535                 st->silk_mode.maxInternalSampleRate = 12000;
536             } else {
537                 st->silk_mode.maxInternalSampleRate = 16000;
538             }
539         }
540         break;
541         case OPUS_GET_BANDWIDTH_REQUEST:
542         {
543             int *value = va_arg(ap, int*);
544             *value = st->bandwidth;
545         }
546         break;
547         case OPUS_SET_DTX_FLAG_REQUEST:
548         {
549             int value = va_arg(ap, int);
550             st->silk_mode.useDTX = value;
551         }
552         break;
553         case OPUS_GET_DTX_FLAG_REQUEST:
554         {
555             int *value = va_arg(ap, int*);
556             *value = st->silk_mode.useDTX;
557         }
558         break;
559         case OPUS_SET_COMPLEXITY_REQUEST:
560         {
561             int value = va_arg(ap, int);
562             st->silk_mode.complexity = value;
563             celt_encoder_ctl(st->celt_enc, CELT_SET_COMPLEXITY(value));
564         }
565         break;
566         case OPUS_GET_COMPLEXITY_REQUEST:
567         {
568             int *value = va_arg(ap, int*);
569             *value = st->silk_mode.complexity;
570         }
571         break;
572         case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
573         {
574             int value = va_arg(ap, int);
575             st->silk_mode.useInBandFEC = value;
576         }
577         break;
578         case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
579         {
580             int *value = va_arg(ap, int*);
581             *value = st->silk_mode.useInBandFEC;
582         }
583         break;
584         case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
585         {
586             int value = va_arg(ap, int);
587             st->silk_mode.packetLossPercentage = value;
588         }
589         break;
590         case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
591         {
592             int *value = va_arg(ap, int*);
593             *value = st->silk_mode.packetLossPercentage;
594         }
595         break;
596         case OPUS_SET_VBR_FLAG_REQUEST:
597         {
598             int value = va_arg(ap, int);
599             st->use_vbr = value;
600             st->silk_mode.useCBR = 1-value;
601         }
602         break;
603         case OPUS_GET_VBR_FLAG_REQUEST:
604         {
605             int *value = va_arg(ap, int*);
606             *value = st->use_vbr;
607         }
608         break;
609         case OPUS_SET_VOICE_RATIO_REQUEST:
610         {
611             int value = va_arg(ap, int);
612             if (value>100 || value<0)
613                 return OPUS_BAD_ARG;
614             st->voice_ratio = value;
615         }
616         break;
617         case OPUS_GET_VOICE_RATIO_REQUEST:
618         {
619             int *value = va_arg(ap, int*);
620             *value = st->voice_ratio;
621         }
622         break;
623         case OPUS_SET_VBR_CONSTRAINT_REQUEST:
624         {
625             int value = va_arg(ap, int);
626             st->vbr_constraint = value;
627         }
628         break;
629         case OPUS_GET_VBR_CONSTRAINT_REQUEST:
630         {
631             int *value = va_arg(ap, int*);
632             *value = st->vbr_constraint;
633         }
634         break;
635         default:
636             fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
637             break;
638     }
639
640     va_end(ap);
641     return OPUS_OK;
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