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