Loss rate adaptation for the CELT layer
[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 = st->stream_channels*st->bitrate_bps/1600;
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: That's OK for now, but we need to set the flags properly */
410         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
411         celt_encode(st->celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
412         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
413     }
414
415     celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band));
416
417     if (st->mode != MODE_SILK_ONLY)
418         {
419             /* Encode high band with CELT */
420             ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
421         }
422
423     /* 5 ms redundant frame for SILK->CELT */
424     if (redundancy && !celt_to_silk)
425     {
426         int N2, N4;
427         N2 = st->Fs/200;
428         N4 = st->Fs/400;
429
430         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
431         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
432         celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
433
434         /* FIXME: Do proper prefilling here */
435         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
436
437         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes);
438     }
439
440
441     if (frame_size>st->encoder_buffer)
442     {
443         for (i=0;i<st->encoder_buffer*st->channels;i++)
444                 st->delay_buffer[i] = pcm[(frame_size-st->encoder_buffer)*st->channels+i];
445     } else {
446         int tmp = st->encoder_buffer-frame_size;
447         for (i=0;i<tmp*st->channels;i++)
448                 st->delay_buffer[i] = st->delay_buffer[i+frame_size*st->channels];
449         for (i=0;i<frame_size*st->channels;i++)
450                 st->delay_buffer[tmp*st->channels+i] = pcm[i];
451     }
452
453         /* Signalling the mode in the first byte */
454         data--;
455         framerate = st->Fs/frame_size;
456         period = 0;
457         while (framerate < 400)
458         {
459             framerate <<= 1;
460             period++;
461         }
462     if (st->mode == MODE_SILK_ONLY)
463     {
464         data[0] = (silk_internal_bandwidth-BANDWIDTH_NARROWBAND)<<5;
465         data[0] |= (period-2)<<3;
466     } else if (st->mode == MODE_CELT_ONLY)
467     {
468         int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
469         if (tmp < 0)
470             tmp = 0;
471         data[0] = 0x80;
472         data[0] |= tmp << 5;
473         data[0] |= period<<3;
474     } else /* Hybrid */
475     {
476         data[0] = 0x60;
477         data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
478         data[0] |= (period-2)<<3;
479     }
480     data[0] |= (st->stream_channels==2)<<2;
481     /*printf ("%x\n", (int)data[0]);*/
482
483 #if OPUS_TEST_RANGE_CODER_STATE
484     st->rangeFinal = enc.rng;
485 #endif
486     if (to_celt)
487         st->prev_mode = MODE_CELT_ONLY;
488     else
489         st->prev_mode = st->mode;
490     return ret+1+redundancy_bytes;
491 }
492
493 int opus_encoder_ctl(OpusEncoder *st, int request, ...)
494 {
495     va_list ap;
496
497     va_start(ap, request);
498
499     switch (request)
500     {
501         case OPUS_SET_MODE_REQUEST:
502         {
503             int value = va_arg(ap, int);
504             st->user_mode = value;
505         }
506         break;
507         case OPUS_GET_MODE_REQUEST:
508         {
509             int *value = va_arg(ap, int*);
510             *value = st->mode;
511         }
512         break;
513         case OPUS_SET_BITRATE_REQUEST:
514         {
515             int value = va_arg(ap, int);
516             st->bitrate_bps = value;
517         }
518         break;
519         case OPUS_GET_BITRATE_REQUEST:
520         {
521             int *value = va_arg(ap, int*);
522             *value = st->bitrate_bps;
523         }
524         break;
525         case OPUS_SET_BANDWIDTH_REQUEST:
526         {
527             int value = va_arg(ap, int);
528             if (value < BANDWIDTH_AUTO || value > BANDWIDTH_FULLBAND)
529                 return OPUS_BAD_ARG;
530             st->user_bandwidth = value;
531             if (st->user_bandwidth == BANDWIDTH_NARROWBAND) {
532                 st->silk_mode.maxInternalSampleRate = 8000;
533             } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
534                 st->silk_mode.maxInternalSampleRate = 12000;
535             } else {
536                 st->silk_mode.maxInternalSampleRate = 16000;
537             }
538         }
539         break;
540         case OPUS_GET_BANDWIDTH_REQUEST:
541         {
542             int *value = va_arg(ap, int*);
543             *value = st->bandwidth;
544         }
545         break;
546         case OPUS_SET_DTX_FLAG_REQUEST:
547         {
548             int value = va_arg(ap, int);
549             st->silk_mode.useDTX = value;
550         }
551         break;
552         case OPUS_GET_DTX_FLAG_REQUEST:
553         {
554             int *value = va_arg(ap, int*);
555             *value = st->silk_mode.useDTX;
556         }
557         break;
558         case OPUS_SET_COMPLEXITY_REQUEST:
559         {
560             int value = va_arg(ap, int);
561             st->silk_mode.complexity = value;
562             celt_encoder_ctl(st->celt_enc, CELT_SET_COMPLEXITY(value));
563         }
564         break;
565         case OPUS_GET_COMPLEXITY_REQUEST:
566         {
567             int *value = va_arg(ap, int*);
568             *value = st->silk_mode.complexity;
569         }
570         break;
571         case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
572         {
573             int value = va_arg(ap, int);
574             st->silk_mode.useInBandFEC = value;
575         }
576         break;
577         case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
578         {
579             int *value = va_arg(ap, int*);
580             *value = st->silk_mode.useInBandFEC;
581         }
582         break;
583         case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
584         {
585             int value = va_arg(ap, int);
586             if (value < 0 || value > 100)
587                 return OPUS_BAD_ARG;
588             st->silk_mode.packetLossPercentage = value;
589             celt_encoder_ctl(st->celt_enc, CELT_SET_LOSS_PERC(value));
590         }
591         break;
592         case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
593         {
594             int *value = va_arg(ap, int*);
595             *value = st->silk_mode.packetLossPercentage;
596         }
597         break;
598         case OPUS_SET_VBR_FLAG_REQUEST:
599         {
600             int value = va_arg(ap, int);
601             st->use_vbr = value;
602             st->silk_mode.useCBR = 1-value;
603         }
604         break;
605         case OPUS_GET_VBR_FLAG_REQUEST:
606         {
607             int *value = va_arg(ap, int*);
608             *value = st->use_vbr;
609         }
610         break;
611         case OPUS_SET_VOICE_RATIO_REQUEST:
612         {
613             int value = va_arg(ap, int);
614             if (value>100 || value<0)
615                 goto bad_arg;
616             st->voice_ratio = value;
617         }
618         break;
619         case OPUS_GET_VOICE_RATIO_REQUEST:
620         {
621             int *value = va_arg(ap, int*);
622             *value = st->voice_ratio;
623         }
624         break;
625         case OPUS_SET_VBR_CONSTRAINT_REQUEST:
626         {
627             int value = va_arg(ap, int);
628             st->vbr_constraint = value;
629         }
630         break;
631         case OPUS_GET_VBR_CONSTRAINT_REQUEST:
632         {
633             int *value = va_arg(ap, int*);
634             *value = st->vbr_constraint;
635         }
636         break;
637         default:
638             fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
639             break;
640     }
641     va_end(ap);
642     return OPUS_OK;
643 bad_arg:
644     va_end(ap);
645     return OPUS_BAD_ARG;
646 }
647
648 void opus_encoder_destroy(OpusEncoder *st)
649 {
650         free(st);
651 }
652
653 #if OPUS_TEST_RANGE_CODER_STATE
654 int opus_encoder_get_final_range(OpusEncoder *st)
655 {
656     return st->rangeFinal;
657 }
658 #endif