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