Merge commit 'silk-repo/master'
[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     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->mode == MODE_CELT_ONLY)
164     {
165         if (mono_rate>35000 || (mono_rate>28000 && st->bandwidth==BANDWIDTH_FULLBAND))
166                 st->bandwidth = BANDWIDTH_FULLBAND;
167         else if (mono_rate>28000 || (mono_rate>24000 && st->bandwidth==BANDWIDTH_SUPERWIDEBAND))
168                 st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
169         else if (mono_rate>24000 || (mono_rate>18000 && st->bandwidth==BANDWIDTH_WIDEBAND))
170                 st->bandwidth = BANDWIDTH_WIDEBAND;
171         else
172                 st->bandwidth = BANDWIDTH_NARROWBAND;
173     } else if (st->first || st->silk_mode.allowBandwidthSwitch)
174     {
175         if (mono_rate>30000 || (mono_rate>26000 && st->bandwidth==BANDWIDTH_FULLBAND))
176                 st->bandwidth = BANDWIDTH_FULLBAND;
177         else if (mono_rate>22000 || (mono_rate>18000 && st->bandwidth==BANDWIDTH_SUPERWIDEBAND))
178                 st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
179         else if (mono_rate>16000 || (mono_rate>13000 && st->bandwidth==BANDWIDTH_WIDEBAND))
180                 st->bandwidth = BANDWIDTH_WIDEBAND;
181         else if (mono_rate>13000 || (mono_rate>10000 && st->bandwidth==BANDWIDTH_MEDIUMBAND))
182                 st->bandwidth = BANDWIDTH_MEDIUMBAND;
183         else
184                 st->bandwidth = BANDWIDTH_NARROWBAND;
185         if (!st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > BANDWIDTH_WIDEBAND)
186                 st->bandwidth = BANDWIDTH_WIDEBAND;
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         if (nBytes==0)
302             return 0;
303         /* Extract SILK internal bandwidth for signaling in first byte */
304         if( st->mode == MODE_SILK_ONLY ) {
305             if( st->silk_mode.internalSampleRate == 8000 ) {
306                 silk_internal_bandwidth = BANDWIDTH_NARROWBAND;
307             } else if( st->silk_mode.internalSampleRate == 12000 ) {
308                 silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND;
309             } else if( st->silk_mode.internalSampleRate == 16000 ) {
310                 silk_internal_bandwidth = BANDWIDTH_WIDEBAND;
311             }
312         } else {
313             SKP_assert( st->silk_mode.internalSampleRate == 16000 );
314         }
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     st->first = 0;
494     return ret+1+redundancy_bytes;
495 }
496
497 int opus_encoder_ctl(OpusEncoder *st, int request, ...)
498 {
499     va_list ap;
500
501     va_start(ap, request);
502
503     switch (request)
504     {
505         case OPUS_SET_MODE_REQUEST:
506         {
507             int value = va_arg(ap, int);
508             st->user_mode = value;
509         }
510         break;
511         case OPUS_GET_MODE_REQUEST:
512         {
513             int *value = va_arg(ap, int*);
514             *value = st->mode;
515         }
516         break;
517         case OPUS_SET_BITRATE_REQUEST:
518         {
519             int value = va_arg(ap, int);
520             st->bitrate_bps = value;
521         }
522         break;
523         case OPUS_GET_BITRATE_REQUEST:
524         {
525             int *value = va_arg(ap, int*);
526             *value = st->bitrate_bps;
527         }
528         break;
529         case OPUS_SET_BANDWIDTH_REQUEST:
530         {
531             int value = va_arg(ap, int);
532             if (value < BANDWIDTH_AUTO || value > BANDWIDTH_FULLBAND)
533                 return OPUS_BAD_ARG;
534             st->user_bandwidth = value;
535             if (st->user_bandwidth == BANDWIDTH_NARROWBAND) {
536                 st->silk_mode.maxInternalSampleRate = 8000;
537             } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
538                 st->silk_mode.maxInternalSampleRate = 12000;
539             } else {
540                 st->silk_mode.maxInternalSampleRate = 16000;
541             }
542         }
543         break;
544         case OPUS_GET_BANDWIDTH_REQUEST:
545         {
546             int *value = va_arg(ap, int*);
547             *value = st->bandwidth;
548         }
549         break;
550         case OPUS_SET_DTX_FLAG_REQUEST:
551         {
552             int value = va_arg(ap, int);
553             st->silk_mode.useDTX = value;
554         }
555         break;
556         case OPUS_GET_DTX_FLAG_REQUEST:
557         {
558             int *value = va_arg(ap, int*);
559             *value = st->silk_mode.useDTX;
560         }
561         break;
562         case OPUS_SET_COMPLEXITY_REQUEST:
563         {
564             int value = va_arg(ap, int);
565             st->silk_mode.complexity = value;
566             celt_encoder_ctl(st->celt_enc, CELT_SET_COMPLEXITY(value));
567         }
568         break;
569         case OPUS_GET_COMPLEXITY_REQUEST:
570         {
571             int *value = va_arg(ap, int*);
572             *value = st->silk_mode.complexity;
573         }
574         break;
575         case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
576         {
577             int value = va_arg(ap, int);
578             st->silk_mode.useInBandFEC = value;
579         }
580         break;
581         case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
582         {
583             int *value = va_arg(ap, int*);
584             *value = st->silk_mode.useInBandFEC;
585         }
586         break;
587         case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
588         {
589             int value = va_arg(ap, int);
590             if (value < 0 || value > 100)
591                 return OPUS_BAD_ARG;
592             st->silk_mode.packetLossPercentage = value;
593             celt_encoder_ctl(st->celt_enc, CELT_SET_LOSS_PERC(value));
594         }
595         break;
596         case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
597         {
598             int *value = va_arg(ap, int*);
599             *value = st->silk_mode.packetLossPercentage;
600         }
601         break;
602         case OPUS_SET_VBR_FLAG_REQUEST:
603         {
604             int value = va_arg(ap, int);
605             st->use_vbr = value;
606             st->silk_mode.useCBR = 1-value;
607         }
608         break;
609         case OPUS_GET_VBR_FLAG_REQUEST:
610         {
611             int *value = va_arg(ap, int*);
612             *value = st->use_vbr;
613         }
614         break;
615         case OPUS_SET_VOICE_RATIO_REQUEST:
616         {
617             int value = va_arg(ap, int);
618             if (value>100 || value<0)
619                 goto bad_arg;
620             st->voice_ratio = value;
621         }
622         break;
623         case OPUS_GET_VOICE_RATIO_REQUEST:
624         {
625             int *value = va_arg(ap, int*);
626             *value = st->voice_ratio;
627         }
628         break;
629         case OPUS_SET_VBR_CONSTRAINT_REQUEST:
630         {
631             int value = va_arg(ap, int);
632             st->vbr_constraint = value;
633         }
634         break;
635         case OPUS_GET_VBR_CONSTRAINT_REQUEST:
636         {
637             int *value = va_arg(ap, int*);
638             *value = st->vbr_constraint;
639         }
640         break;
641         default:
642             fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
643             break;
644     }
645     va_end(ap);
646     return OPUS_OK;
647 bad_arg:
648     va_end(ap);
649     return OPUS_BAD_ARG;
650 }
651
652 void opus_encoder_destroy(OpusEncoder *st)
653 {
654         free(st);
655 }
656
657 #if OPUS_TEST_RANGE_CODER_STATE
658 int opus_encoder_get_final_range(OpusEncoder *st)
659 {
660     return st->rangeFinal;
661 }
662 #endif