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