Fixes 60 ms speech 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.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->first = 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     /* TODO: This is 60 only so we can handle 60ms speech/audio switching 
115        it shouldn't bee too hard to reduce to 20 ms if needed */
116     short pcm_buf[3*960*2];
117     int nb_compr_bytes;
118     int to_celt = 0;
119     celt_int32 mono_rate;
120
121     if (st->channels == 2)
122     {
123         celt_int32 decision_rate;
124         decision_rate = st->bitrate_bps + st->voice_ratio*st->voice_ratio;
125         if (st->stream_channels == 2)
126             decision_rate += 4000;
127         else
128             decision_rate -= 4000;
129         if (decision_rate>48000)
130             st->stream_channels = 2;
131         else
132             st->stream_channels = 1;
133     } else {
134         st->stream_channels = 1;
135     }
136     /* Equivalent bit-rate for mono */
137     mono_rate = st->bitrate_bps;
138     if (st->stream_channels==2)
139         mono_rate = (mono_rate+10000)/2;
140     /* Compensate for smaller frame sizes assuming an equivalent overhead
141        of 60 bits/frame */
142     mono_rate -= 60*(st->Fs/frame_size - 50);
143
144     /* Mode selection */
145     if (st->user_mode==OPUS_MODE_AUTO)
146     {
147         celt_int32 decision_rate;
148         decision_rate = mono_rate - 3*st->voice_ratio*st->voice_ratio;
149         if (st->prev_mode == MODE_CELT_ONLY)
150             decision_rate += 4000;
151         else if (st->prev_mode>0)
152             decision_rate -= 4000;
153         if (decision_rate>24000)
154             st->mode = MODE_CELT_ONLY;
155         else
156             st->mode = MODE_SILK_ONLY;
157     } else if (st->user_mode==OPUS_MODE_VOICE)
158     {
159         st->mode = MODE_SILK_ONLY;
160     } else {/* OPUS_AUDIO_MODE */
161         st->mode = MODE_CELT_ONLY;
162     }
163
164     /* Bandwidth selection */
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 if (st->first || st->silk_mode.allowBandwidthSwitch)
176     {
177         if (mono_rate>30000 || (mono_rate>26000 && st->bandwidth==BANDWIDTH_FULLBAND))
178                 st->bandwidth = BANDWIDTH_FULLBAND;
179         else if (mono_rate>22000 || (mono_rate>18000 && st->bandwidth==BANDWIDTH_SUPERWIDEBAND))
180                 st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
181         else if (mono_rate>16000 || (mono_rate>13000 && st->bandwidth==BANDWIDTH_WIDEBAND))
182                 st->bandwidth = BANDWIDTH_WIDEBAND;
183         else if (mono_rate>13000 || (mono_rate>10000 && st->bandwidth==BANDWIDTH_MEDIUMBAND))
184                 st->bandwidth = BANDWIDTH_MEDIUMBAND;
185         else
186                 st->bandwidth = BANDWIDTH_NARROWBAND;
187         if (!st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > BANDWIDTH_WIDEBAND)
188                 st->bandwidth = BANDWIDTH_WIDEBAND;
189     }
190
191     if (st->Fs <= 24000 && st->bandwidth > BANDWIDTH_SUPERWIDEBAND)
192         st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
193     if (st->Fs <= 16000 && st->bandwidth > BANDWIDTH_WIDEBAND)
194         st->bandwidth = BANDWIDTH_WIDEBAND;
195     if (st->Fs <= 12000 && st->bandwidth > BANDWIDTH_MEDIUMBAND)
196         st->bandwidth = BANDWIDTH_MEDIUMBAND;
197     if (st->Fs <= 8000 && st->bandwidth > BANDWIDTH_NARROWBAND)
198         st->bandwidth = BANDWIDTH_NARROWBAND;
199
200     if (st->user_bandwidth != BANDWIDTH_AUTO)
201         st->bandwidth = st->user_bandwidth;
202
203     /* Preventing non-sensical configurations */
204     if (frame_size < st->Fs/100 && st->mode != MODE_CELT_ONLY)
205         st->mode = MODE_CELT_ONLY;
206     if (frame_size > st->Fs/50 && st->mode != MODE_SILK_ONLY)
207         st->mode = MODE_SILK_ONLY;
208     if (st->mode == MODE_CELT_ONLY && st->bandwidth == BANDWIDTH_MEDIUMBAND)
209         st->bandwidth = BANDWIDTH_WIDEBAND;
210     if (st->mode == MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND)
211         st->mode = MODE_HYBRID;
212     if (st->mode == MODE_HYBRID && st->bandwidth <= BANDWIDTH_WIDEBAND)
213         st->mode = MODE_SILK_ONLY;
214
215         bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
216
217         data += 1;
218         if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
219         {
220                 SKP_SILK_SDK_EncControlStruct dummy;
221                 SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy);
222                 prefill=1;
223         }
224         if (st->prev_mode >0 &&
225                 ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
226                 || (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
227         {
228             redundancy = 1;
229             celt_to_silk = (st->mode != MODE_CELT_ONLY);
230             if (!celt_to_silk)
231             {
232                 /* Switch to SILK/hybrid if frame size is 10 ms or more*/
233                 if (frame_size >= st->Fs/100)
234                 {
235                         st->mode = st->prev_mode;
236                         to_celt = 1;
237                 } else {
238                         redundancy=0;
239                 }
240             }
241         }
242
243         ec_enc_init(&enc, data, max_data_bytes-1);
244
245         /* SILK processing */
246     if (st->mode != MODE_CELT_ONLY)
247     {
248         st->silk_mode.bitRate = st->bitrate_bps - 8*st->Fs/frame_size;
249         if( st->mode == MODE_HYBRID ) {
250             if( st->bandwidth == BANDWIDTH_SUPERWIDEBAND ) {
251                 if( st->Fs == 100 * frame_size ) {
252                     /* 24 kHz, 10 ms */
253                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3;
254                 } else {
255                     /* 24 kHz, 20 ms */
256                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3;
257                 }
258             } else {
259                 if( st->Fs == 100 * frame_size ) {
260                     /* 48 kHz, 10 ms */
261                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2;
262                 } else {
263                     /* 48 kHz, 20 ms */
264                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2;
265                 }
266             }
267             /* don't let SILK use more than 80% */
268             if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) {
269                 st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5;
270             }
271         }
272
273         st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
274         if (st->bandwidth == BANDWIDTH_NARROWBAND) {
275                 st->silk_mode.desiredInternalSampleRate = 8000;
276         } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
277                 st->silk_mode.desiredInternalSampleRate = 12000;
278         } else {
279             SKP_assert( st->mode == MODE_HYBRID || st->bandwidth == BANDWIDTH_WIDEBAND );
280             st->silk_mode.desiredInternalSampleRate = 16000;
281         }
282         if( st->mode == MODE_HYBRID ) {
283             /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
284             st->silk_mode.minInternalSampleRate = 16000;
285         } else {
286             st->silk_mode.minInternalSampleRate = 8000;
287         }
288         st->silk_mode.maxInternalSampleRate = 16000;
289
290         /* Call SILK encoder for the low band */
291         nBytes = max_data_bytes-1;
292         if (prefill)
293         {
294             int zero=0;
295                 SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, st->delay_buffer, st->encoder_buffer, NULL, &zero, 1 );
296         }
297
298         ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 );
299         if( ret ) {
300             fprintf (stderr, "SILK encode error: %d\n", ret);
301             /* Handle error */
302         }
303         if (nBytes==0)
304             return 0;
305         /* Extract SILK internal bandwidth for signaling in first byte */
306         if( st->mode == MODE_SILK_ONLY ) {
307             if( st->silk_mode.internalSampleRate == 8000 ) {
308                 silk_internal_bandwidth = BANDWIDTH_NARROWBAND;
309             } else if( st->silk_mode.internalSampleRate == 12000 ) {
310                 silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND;
311             } else if( st->silk_mode.internalSampleRate == 16000 ) {
312                 silk_internal_bandwidth = BANDWIDTH_WIDEBAND;
313             }
314         } else {
315             SKP_assert( st->silk_mode.internalSampleRate == 16000 );
316         }
317     }
318
319     /* CELT processing */
320         {
321             int endband=21;
322
323             switch(st->bandwidth)
324             {
325             case BANDWIDTH_NARROWBAND:
326                 endband = 13;
327                 break;
328             case BANDWIDTH_WIDEBAND:
329                 endband = 17;
330                 break;
331             case BANDWIDTH_SUPERWIDEBAND:
332                 endband = 19;
333                 break;
334             case BANDWIDTH_FULLBAND:
335                 endband = 21;
336                 break;
337             }
338             celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband));
339             celt_encoder_ctl(st->celt_enc, CELT_SET_CHANNELS(st->stream_channels));
340         }
341         if (st->mode != MODE_SILK_ONLY)
342         {
343         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
344         celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000));
345         if (st->prev_mode == MODE_SILK_ONLY)
346         {
347                 unsigned char dummy[10];
348                 celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
349                 celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
350                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
351                 /* FIXME: This wastes CPU a bit compared to just prefilling the buffer */
352                 celt_encode(st->celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10);
353         } else {
354                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2));
355         }
356
357         if (st->mode == MODE_HYBRID)
358         {
359             int len;
360
361             len = (ec_tell(&enc)+7)>>3;
362             if( st->use_vbr ) {
363                 nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
364             } else {
365                 /* check if SILK used up too much */
366                 nb_compr_bytes = len > bytes_target ? len : bytes_target;
367             }
368         } else {
369             if (st->use_vbr)
370             {
371                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
372                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint));
373                 celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps));
374                 nb_compr_bytes = max_data_bytes-1;
375             } else {
376                 nb_compr_bytes = bytes_target;
377             }
378         }
379
380         ec_enc_shrink(&enc, nb_compr_bytes);
381         } else {
382             nb_compr_bytes = 0;
383         }
384
385     for (i=0;i<IMIN(frame_size, st->delay_compensation)*st->channels;i++)
386         pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation)*st->channels+i];
387     for (;i<frame_size*st->channels;i++)
388         pcm_buf[i] = pcm[i-st->delay_compensation*st->channels];
389     if (st->mode != MODE_CELT_ONLY)
390     {
391         /* Check if we have a redundant 0-8 kHz band */
392         ec_enc_bit_logp(&enc, redundancy, 12);
393         if (redundancy)
394         {
395             redundancy_bytes = st->stream_channels*st->bitrate_bps/1600;
396             ec_enc_bit_logp(&enc, celt_to_silk, 1);
397             if (st->mode == MODE_HYBRID)
398                 ec_enc_uint(&enc, redundancy_bytes-2, 256);
399         }
400         start_band = 17;
401     }
402
403     if (st->mode == MODE_SILK_ONLY)
404     {
405         ret = (ec_tell(&enc)+7)>>3;
406         ec_enc_done(&enc);
407         nb_compr_bytes = ret;
408     }
409
410     /* 5 ms redundant frame for CELT->SILK */
411     if (redundancy && celt_to_silk)
412     {
413         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
414         /* FIXME: That's OK for now, but we need to set the flags properly */
415         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
416         celt_encode(st->celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
417         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
418     }
419
420     celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band));
421
422     if (st->mode != MODE_SILK_ONLY)
423         {
424             /* Encode high band with CELT */
425             ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
426         }
427
428     /* 5 ms redundant frame for SILK->CELT */
429     if (redundancy && !celt_to_silk)
430     {
431         int N2, N4;
432         N2 = st->Fs/200;
433         N4 = st->Fs/400;
434
435         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
436         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
437         celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
438
439         /* FIXME: Do proper prefilling here */
440         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
441
442         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes);
443     }
444
445
446     if (frame_size>st->encoder_buffer)
447     {
448         for (i=0;i<st->encoder_buffer*st->channels;i++)
449                 st->delay_buffer[i] = pcm[(frame_size-st->encoder_buffer)*st->channels+i];
450     } else {
451         int tmp = st->encoder_buffer-frame_size;
452         for (i=0;i<tmp*st->channels;i++)
453                 st->delay_buffer[i] = st->delay_buffer[i+frame_size*st->channels];
454         for (i=0;i<frame_size*st->channels;i++)
455                 st->delay_buffer[tmp*st->channels+i] = pcm[i];
456     }
457
458         /* Signalling the mode in the first byte */
459         data--;
460         framerate = st->Fs/frame_size;
461         period = 0;
462         while (framerate < 400)
463         {
464             framerate <<= 1;
465             period++;
466         }
467     if (st->mode == MODE_SILK_ONLY)
468     {
469         data[0] = (silk_internal_bandwidth-BANDWIDTH_NARROWBAND)<<5;
470         data[0] |= (period-2)<<3;
471     } else if (st->mode == MODE_CELT_ONLY)
472     {
473         int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
474         if (tmp < 0)
475             tmp = 0;
476         data[0] = 0x80;
477         data[0] |= tmp << 5;
478         data[0] |= period<<3;
479     } else /* Hybrid */
480     {
481         data[0] = 0x60;
482         data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
483         data[0] |= (period-2)<<3;
484     }
485     data[0] |= (st->stream_channels==2)<<2;
486     /*printf ("%x\n", (int)data[0]);*/
487
488 #if OPUS_TEST_RANGE_CODER_STATE
489     st->rangeFinal = enc.rng;
490 #endif
491     if (to_celt)
492         st->prev_mode = MODE_CELT_ONLY;
493     else
494         st->prev_mode = st->mode;
495     st->first = 0;
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