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