12909671c35d1308f1147e2c0e726e25912161b4
[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 /* Transition table for the voice mode */
42 static const int voice_bandwidth_thresholds[10] = {
43                 11500, 1500, /* NB<->MB */
44                 14500, 1500, /* MB<->WB */
45                 21000, 2000, /* WB<->SWB */
46                 29000, 2000, /* SWB<->FB */
47 };
48 /* Transition table for the audio mode */
49 static const int audio_bandwidth_thresholds[10] = {
50                 30000,    0, /* MB not allowed */
51                 20000, 2000, /* MB<->WB */
52                 26000, 2000, /* WB<->SWB */
53                 33000, 2000, /* SWB<->FB */
54 };
55
56
57 OpusEncoder *opus_encoder_create(int Fs, int channels)
58 {
59     int err;
60     char *raw_state;
61         OpusEncoder *st;
62         int ret, silkEncSizeBytes, celtEncSizeBytes;
63
64     /* Create SILK encoder */
65     ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes );
66     if( ret ) {
67         /* Handle error */
68     }
69     celtEncSizeBytes = celt_encoder_get_size(channels);
70     raw_state = calloc(sizeof(OpusEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1);
71     st = (OpusEncoder*)raw_state;
72     st->silk_enc = (void*)(raw_state+sizeof(OpusEncoder));
73     st->celt_enc = (CELTEncoder*)(raw_state+sizeof(OpusEncoder)+silkEncSizeBytes);
74     st->stream_channels = st->channels = channels;
75
76     st->Fs = Fs;
77
78     ret = SKP_Silk_SDK_InitEncoder( st->silk_enc, &st->silk_mode );
79     if( ret ) {
80         /* Handle error */
81     }
82
83     /* default SILK parameters */
84     st->silk_mode.API_sampleRate        = st->Fs;
85     st->silk_mode.nChannels             = channels;
86     st->silk_mode.maxInternalSampleRate = 16000;
87     st->silk_mode.minInternalSampleRate = 8000;
88     st->silk_mode.payloadSize_ms        = 20;
89     st->silk_mode.packetLossPercentage  = 0;
90     st->silk_mode.useInBandFEC          = 0;
91     st->silk_mode.useDTX                = 0;
92     st->silk_mode.complexity            = 10;
93
94     /* Create CELT encoder */
95         /* Initialize CELT encoder */
96         st->celt_enc = celt_encoder_init(st->celt_enc, Fs, channels, &err);
97     celt_encoder_ctl(st->celt_enc, CELT_SET_SIGNALLING(0));
98
99         st->mode = MODE_HYBRID;
100         st->bandwidth = BANDWIDTH_FULLBAND;
101         st->use_vbr = 0;
102         st->bitrate_bps = 32000;
103         st->user_mode = OPUS_MODE_AUTO;
104         st->user_bandwidth = BANDWIDTH_AUTO;
105         st->voice_ratio = 90;
106         st->first = 1;
107
108         st->encoder_buffer = st->Fs/100;
109         st->delay_compensation = st->Fs/400;
110         if (st->Fs > 16000)
111                 st->delay_compensation += 10;
112         return st;
113 }
114
115 int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
116                 unsigned char *data, int max_data_bytes)
117 {
118     int i;
119         int ret=0;
120         SKP_int32 nBytes;
121         ec_enc enc;
122         int framerate, period;
123     int silk_internal_bandwidth;
124     int bytes_target;
125     int prefill=0;
126     int start_band = 0;
127     int redundancy = 0;
128     int redundancy_bytes = 0;
129     int celt_to_silk = 0;
130     /* TODO: This is 60 only so we can handle 60ms speech/audio switching 
131        it shouldn't bee too hard to reduce to 20 ms if needed */
132     short pcm_buf[3*960*2];
133     int nb_compr_bytes;
134     int to_celt = 0;
135     celt_int32 mono_rate;
136
137     /* Rete-dependent mono-stereo decision */
138     if (st->channels == 2)
139     {
140         celt_int32 decision_rate;
141         decision_rate = st->bitrate_bps + st->voice_ratio*st->voice_ratio;
142         /* Add some hysteresis */
143         if (st->stream_channels == 2)
144             decision_rate += 4000;
145         else
146             decision_rate -= 4000;
147         if (decision_rate>48000)
148             st->stream_channels = 2;
149         else
150             st->stream_channels = 1;
151     } else {
152         st->stream_channels = 1;
153     }
154     /* Equivalent bit-rate for mono */
155     mono_rate = st->bitrate_bps;
156     if (st->stream_channels==2)
157         mono_rate = (mono_rate+10000)/2;
158     /* Compensate for smaller frame sizes assuming an equivalent overhead
159        of 60 bits/frame */
160     mono_rate -= 60*(st->Fs/frame_size - 50);
161
162     /* Mode selection */
163     if (st->user_mode==OPUS_MODE_AUTO)
164     {
165         celt_int32 decision_rate;
166         /* SILK/CELT threshold is higher for voice than for music */
167         decision_rate = mono_rate - 3*st->voice_ratio*st->voice_ratio;
168         /* Hysteresis */
169         if (st->prev_mode == MODE_CELT_ONLY)
170             decision_rate += 4000;
171         else if (st->prev_mode>0)
172             decision_rate -= 4000;
173         if (decision_rate>24000)
174             st->mode = MODE_CELT_ONLY;
175         else
176             st->mode = MODE_SILK_ONLY;
177     } else if (st->user_mode==OPUS_MODE_VOICE)
178     {
179         st->mode = MODE_SILK_ONLY;
180     } else {/* OPUS_AUDIO_MODE */
181         st->mode = MODE_CELT_ONLY;
182     }
183
184     /* Automatic (rate-dependent) bandwidth selection */
185     if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
186     {
187         const int *bandwidth_thresholds;
188         int bandwidth = BANDWIDTH_FULLBAND;
189
190         bandwidth_thresholds = st->mode == MODE_CELT_ONLY ? audio_bandwidth_thresholds : voice_bandwidth_thresholds;
191         do {
192                 int threshold, hysteresis;
193                 threshold = bandwidth_thresholds[2*(bandwidth-BANDWIDTH_MEDIUMBAND)];
194                 hysteresis = bandwidth_thresholds[2*(bandwidth-BANDWIDTH_MEDIUMBAND)+1];
195                 if (!st->first)
196                 {
197                         if (st->bandwidth >= bandwidth)
198                                 threshold -= hysteresis;
199                         else
200                                 threshold += hysteresis;
201                 }
202                 if (mono_rate >= threshold)
203                         break;
204         } while (--bandwidth>BANDWIDTH_NARROWBAND);
205         st->bandwidth = bandwidth;
206         /* Prevents any transition to SWB/FB until the SILK layer has fully
207            switched to WB mode and turned the variable LP filter off */
208         if (st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > BANDWIDTH_WIDEBAND)
209                 st->bandwidth = BANDWIDTH_WIDEBAND;
210     }
211
212     /* Prevents Opus from wasting bits on frequencies that are above
213        the Nyquist rate of the input signal */
214     if (st->Fs <= 24000 && st->bandwidth > BANDWIDTH_SUPERWIDEBAND)
215         st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
216     if (st->Fs <= 16000 && st->bandwidth > BANDWIDTH_WIDEBAND)
217         st->bandwidth = BANDWIDTH_WIDEBAND;
218     if (st->Fs <= 12000 && st->bandwidth > BANDWIDTH_MEDIUMBAND)
219         st->bandwidth = BANDWIDTH_MEDIUMBAND;
220     if (st->Fs <= 8000 && st->bandwidth > BANDWIDTH_NARROWBAND)
221         st->bandwidth = BANDWIDTH_NARROWBAND;
222
223     if (st->user_bandwidth != BANDWIDTH_AUTO)
224         st->bandwidth = st->user_bandwidth;
225
226     /* Prevents nonsensical configurations, i.e. modes that don't exist */
227     if (frame_size < st->Fs/100 && st->mode != MODE_CELT_ONLY)
228         st->mode = MODE_CELT_ONLY;
229     if (frame_size > st->Fs/50 && st->mode != MODE_SILK_ONLY)
230         st->mode = MODE_SILK_ONLY;
231     if (st->mode == MODE_CELT_ONLY && st->bandwidth == BANDWIDTH_MEDIUMBAND)
232         st->bandwidth = BANDWIDTH_WIDEBAND;
233     if (st->mode == MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND)
234         st->mode = MODE_HYBRID;
235     if (st->mode == MODE_HYBRID && st->bandwidth <= BANDWIDTH_WIDEBAND)
236         st->mode = MODE_SILK_ONLY;
237
238         bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
239
240         data += 1;
241         if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
242         {
243                 SKP_SILK_SDK_EncControlStruct dummy;
244                 SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy);
245                 prefill=1;
246         }
247         if (st->prev_mode >0 &&
248                 ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
249                 || (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
250         {
251             redundancy = 1;
252             celt_to_silk = (st->mode != MODE_CELT_ONLY);
253             if (!celt_to_silk)
254             {
255                 /* Switch to SILK/hybrid if frame size is 10 ms or more*/
256                 if (frame_size >= st->Fs/100)
257                 {
258                         st->mode = st->prev_mode;
259                         to_celt = 1;
260                 } else {
261                         redundancy=0;
262                 }
263             }
264         }
265
266         ec_enc_init(&enc, data, max_data_bytes-1);
267
268         /* SILK processing */
269     if (st->mode != MODE_CELT_ONLY)
270     {
271         st->silk_mode.bitRate = st->bitrate_bps - 8*st->Fs/frame_size;
272         if( st->mode == MODE_HYBRID ) {
273             if( st->bandwidth == BANDWIDTH_SUPERWIDEBAND ) {
274                 if( st->Fs == 100 * frame_size ) {
275                     /* 24 kHz, 10 ms */
276                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3;
277                 } else {
278                     /* 24 kHz, 20 ms */
279                     st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3;
280                 }
281             } else {
282                 if( st->Fs == 100 * frame_size ) {
283                     /* 48 kHz, 10 ms */
284                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2;
285                 } else {
286                     /* 48 kHz, 20 ms */
287                     st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2;
288                 }
289             }
290             /* don't let SILK use more than 80% */
291             if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) {
292                 st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5;
293             }
294         }
295
296         st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
297         if (st->bandwidth == BANDWIDTH_NARROWBAND) {
298                 st->silk_mode.desiredInternalSampleRate = 8000;
299         } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
300                 st->silk_mode.desiredInternalSampleRate = 12000;
301         } else {
302             SKP_assert( st->mode == MODE_HYBRID || st->bandwidth == BANDWIDTH_WIDEBAND );
303             st->silk_mode.desiredInternalSampleRate = 16000;
304         }
305         if( st->mode == MODE_HYBRID ) {
306             /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
307             st->silk_mode.minInternalSampleRate = 16000;
308         } else {
309             st->silk_mode.minInternalSampleRate = 8000;
310         }
311         st->silk_mode.maxInternalSampleRate = 16000;
312
313         /* Call SILK encoder for the low band */
314         nBytes = max_data_bytes-1;
315         if (prefill)
316         {
317             int zero=0;
318                 SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, st->delay_buffer, st->encoder_buffer, NULL, &zero, 1 );
319         }
320
321         ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 );
322         if( ret ) {
323             fprintf (stderr, "SILK encode error: %d\n", ret);
324             /* Handle error */
325         }
326         if (nBytes==0)
327             return 0;
328         /* Extract SILK internal bandwidth for signaling in first byte */
329         if( st->mode == MODE_SILK_ONLY ) {
330             if( st->silk_mode.internalSampleRate == 8000 ) {
331                 silk_internal_bandwidth = BANDWIDTH_NARROWBAND;
332             } else if( st->silk_mode.internalSampleRate == 12000 ) {
333                 silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND;
334             } else if( st->silk_mode.internalSampleRate == 16000 ) {
335                 silk_internal_bandwidth = BANDWIDTH_WIDEBAND;
336             }
337         } else {
338             SKP_assert( st->silk_mode.internalSampleRate == 16000 );
339         }
340     }
341
342     /* CELT processing */
343         {
344             int endband=21;
345
346             switch(st->bandwidth)
347             {
348             case BANDWIDTH_NARROWBAND:
349                 endband = 13;
350                 break;
351             case BANDWIDTH_WIDEBAND:
352                 endband = 17;
353                 break;
354             case BANDWIDTH_SUPERWIDEBAND:
355                 endband = 19;
356                 break;
357             case BANDWIDTH_FULLBAND:
358                 endband = 21;
359                 break;
360             }
361             celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband));
362             celt_encoder_ctl(st->celt_enc, CELT_SET_CHANNELS(st->stream_channels));
363         }
364         if (st->mode != MODE_SILK_ONLY)
365         {
366         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
367         celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000));
368         if (st->prev_mode == MODE_SILK_ONLY)
369         {
370                 unsigned char dummy[10];
371                 celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
372                 celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
373                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
374                 /* FIXME: This wastes CPU a bit compared to just prefilling the buffer */
375                 celt_encode(st->celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10);
376         } else {
377                 celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2));
378         }
379
380         if (st->mode == MODE_HYBRID)
381         {
382             int len;
383
384             len = (ec_tell(&enc)+7)>>3;
385             if( st->use_vbr ) {
386                 nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
387             } else {
388                 /* check if SILK used up too much */
389                 nb_compr_bytes = len > bytes_target ? len : bytes_target;
390             }
391         } else {
392             if (st->use_vbr)
393             {
394                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
395                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint));
396                 celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps));
397                 nb_compr_bytes = max_data_bytes-1;
398             } else {
399                 nb_compr_bytes = bytes_target;
400             }
401         }
402
403         ec_enc_shrink(&enc, nb_compr_bytes);
404         } else {
405             nb_compr_bytes = 0;
406         }
407
408     for (i=0;i<IMIN(frame_size, st->delay_compensation)*st->channels;i++)
409         pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation)*st->channels+i];
410     for (;i<frame_size*st->channels;i++)
411         pcm_buf[i] = pcm[i-st->delay_compensation*st->channels];
412     if (st->mode != MODE_CELT_ONLY)
413     {
414         /* Check if we have a redundant 0-8 kHz band */
415         ec_enc_bit_logp(&enc, redundancy, 12);
416         if (redundancy)
417         {
418             redundancy_bytes = st->stream_channels*st->bitrate_bps/1600;
419             ec_enc_bit_logp(&enc, celt_to_silk, 1);
420             if (st->mode == MODE_HYBRID)
421                 ec_enc_uint(&enc, redundancy_bytes-2, 256);
422         }
423         start_band = 17;
424     }
425
426     if (st->mode == MODE_SILK_ONLY)
427     {
428         ret = (ec_tell(&enc)+7)>>3;
429         ec_enc_done(&enc);
430         nb_compr_bytes = ret;
431     }
432
433     /* 5 ms redundant frame for CELT->SILK */
434     if (redundancy && celt_to_silk)
435     {
436         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
437         /* FIXME: That's OK for now, but we need to set the flags properly */
438         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
439         celt_encode(st->celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
440         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
441     }
442
443     celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band));
444
445     if (st->mode != MODE_SILK_ONLY)
446         {
447             /* Encode high band with CELT */
448             ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
449         }
450
451     /* 5 ms redundant frame for SILK->CELT */
452     if (redundancy && !celt_to_silk)
453     {
454         int N2, N4;
455         N2 = st->Fs/200;
456         N4 = st->Fs/400;
457
458         celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
459         celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
460         celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
461
462         /* FIXME: Do proper prefilling here */
463         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
464
465         celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes);
466     }
467
468
469     if (frame_size>st->encoder_buffer)
470     {
471         for (i=0;i<st->encoder_buffer*st->channels;i++)
472                 st->delay_buffer[i] = pcm[(frame_size-st->encoder_buffer)*st->channels+i];
473     } else {
474         int tmp = st->encoder_buffer-frame_size;
475         for (i=0;i<tmp*st->channels;i++)
476                 st->delay_buffer[i] = st->delay_buffer[i+frame_size*st->channels];
477         for (i=0;i<frame_size*st->channels;i++)
478                 st->delay_buffer[tmp*st->channels+i] = pcm[i];
479     }
480
481         /* Signalling the mode in the first byte */
482         data--;
483         framerate = st->Fs/frame_size;
484         period = 0;
485         while (framerate < 400)
486         {
487             framerate <<= 1;
488             period++;
489         }
490     if (st->mode == MODE_SILK_ONLY)
491     {
492         data[0] = (silk_internal_bandwidth-BANDWIDTH_NARROWBAND)<<5;
493         data[0] |= (period-2)<<3;
494     } else if (st->mode == MODE_CELT_ONLY)
495     {
496         int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
497         if (tmp < 0)
498             tmp = 0;
499         data[0] = 0x80;
500         data[0] |= tmp << 5;
501         data[0] |= period<<3;
502     } else /* Hybrid */
503     {
504         data[0] = 0x60;
505         data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
506         data[0] |= (period-2)<<3;
507     }
508     data[0] |= (st->stream_channels==2)<<2;
509     /*printf ("%x\n", (int)data[0]);*/
510
511 #if OPUS_TEST_RANGE_CODER_STATE
512     st->rangeFinal = enc.rng;
513 #endif
514     if (to_celt)
515         st->prev_mode = MODE_CELT_ONLY;
516     else
517         st->prev_mode = st->mode;
518     st->first = 0;
519     return ret+1+redundancy_bytes;
520 }
521
522 int opus_encoder_ctl(OpusEncoder *st, int request, ...)
523 {
524     va_list ap;
525
526     va_start(ap, request);
527
528     switch (request)
529     {
530         case OPUS_SET_MODE_REQUEST:
531         {
532             int value = va_arg(ap, int);
533             st->user_mode = value;
534         }
535         break;
536         case OPUS_GET_MODE_REQUEST:
537         {
538             int *value = va_arg(ap, int*);
539             *value = st->mode;
540         }
541         break;
542         case OPUS_SET_BITRATE_REQUEST:
543         {
544             int value = va_arg(ap, int);
545             st->bitrate_bps = value;
546         }
547         break;
548         case OPUS_GET_BITRATE_REQUEST:
549         {
550             int *value = va_arg(ap, int*);
551             *value = st->bitrate_bps;
552         }
553         break;
554         case OPUS_SET_BANDWIDTH_REQUEST:
555         {
556             int value = va_arg(ap, int);
557             if (value < BANDWIDTH_AUTO || value > BANDWIDTH_FULLBAND)
558                 return OPUS_BAD_ARG;
559             st->user_bandwidth = value;
560             if (st->user_bandwidth == BANDWIDTH_NARROWBAND) {
561                 st->silk_mode.maxInternalSampleRate = 8000;
562             } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
563                 st->silk_mode.maxInternalSampleRate = 12000;
564             } else {
565                 st->silk_mode.maxInternalSampleRate = 16000;
566             }
567         }
568         break;
569         case OPUS_GET_BANDWIDTH_REQUEST:
570         {
571             int *value = va_arg(ap, int*);
572             *value = st->bandwidth;
573         }
574         break;
575         case OPUS_SET_DTX_FLAG_REQUEST:
576         {
577             int value = va_arg(ap, int);
578             st->silk_mode.useDTX = value;
579         }
580         break;
581         case OPUS_GET_DTX_FLAG_REQUEST:
582         {
583             int *value = va_arg(ap, int*);
584             *value = st->silk_mode.useDTX;
585         }
586         break;
587         case OPUS_SET_COMPLEXITY_REQUEST:
588         {
589             int value = va_arg(ap, int);
590             st->silk_mode.complexity = value;
591             celt_encoder_ctl(st->celt_enc, CELT_SET_COMPLEXITY(value));
592         }
593         break;
594         case OPUS_GET_COMPLEXITY_REQUEST:
595         {
596             int *value = va_arg(ap, int*);
597             *value = st->silk_mode.complexity;
598         }
599         break;
600         case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
601         {
602             int value = va_arg(ap, int);
603             st->silk_mode.useInBandFEC = value;
604         }
605         break;
606         case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
607         {
608             int *value = va_arg(ap, int*);
609             *value = st->silk_mode.useInBandFEC;
610         }
611         break;
612         case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
613         {
614             int value = va_arg(ap, int);
615             if (value < 0 || value > 100)
616                 return OPUS_BAD_ARG;
617             st->silk_mode.packetLossPercentage = value;
618             celt_encoder_ctl(st->celt_enc, CELT_SET_LOSS_PERC(value));
619         }
620         break;
621         case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
622         {
623             int *value = va_arg(ap, int*);
624             *value = st->silk_mode.packetLossPercentage;
625         }
626         break;
627         case OPUS_SET_VBR_FLAG_REQUEST:
628         {
629             int value = va_arg(ap, int);
630             st->use_vbr = value;
631             st->silk_mode.useCBR = 1-value;
632         }
633         break;
634         case OPUS_GET_VBR_FLAG_REQUEST:
635         {
636             int *value = va_arg(ap, int*);
637             *value = st->use_vbr;
638         }
639         break;
640         case OPUS_SET_VOICE_RATIO_REQUEST:
641         {
642             int value = va_arg(ap, int);
643             if (value>100 || value<0)
644                 goto bad_arg;
645             st->voice_ratio = value;
646         }
647         break;
648         case OPUS_GET_VOICE_RATIO_REQUEST:
649         {
650             int *value = va_arg(ap, int*);
651             *value = st->voice_ratio;
652         }
653         break;
654         case OPUS_SET_VBR_CONSTRAINT_REQUEST:
655         {
656             int value = va_arg(ap, int);
657             st->vbr_constraint = value;
658         }
659         break;
660         case OPUS_GET_VBR_CONSTRAINT_REQUEST:
661         {
662             int *value = va_arg(ap, int*);
663             *value = st->vbr_constraint;
664         }
665         break;
666         default:
667             fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
668             break;
669     }
670     va_end(ap);
671     return OPUS_OK;
672 bad_arg:
673     va_end(ap);
674     return OPUS_BAD_ARG;
675 }
676
677 void opus_encoder_destroy(OpusEncoder *st)
678 {
679         free(st);
680 }
681
682 #if OPUS_TEST_RANGE_CODER_STATE
683 int opus_encoder_get_final_range(OpusEncoder *st)
684 {
685     return st->rangeFinal;
686 }
687 #endif