blob: 25c9c4e4353f973bad7d8af742e72a540b01bba7 [file] [log] [blame]
Jean-Marc Valin6696a142011-08-22 10:40:38 -04001/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
Jean-Marc Valinfbaabc12010-07-05 15:47:04 -04002 Written by Jean-Marc Valin and Koen Vos */
Jean-Marc Valin3e66e912010-06-30 14:16:14 -04003/*
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
Jean-Marc Valin3e66e912010-06-30 14:16:14 -040015 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
Jean-Marc Valincb05e7c2012-04-20 16:40:24 -040018 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Jean-Marc Valin3e66e912010-06-30 14:16:14 -040020 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
Jean-Marc Valin24f36e02010-07-06 14:41:20 -040032#include <stdarg.h>
Jean-Marc Valin8ea67042011-03-11 17:49:10 -050033#include "celt.h"
Jean-Marc Valina0cbeca2010-07-08 11:27:20 -040034#include "entenc.h"
35#include "modes.h"
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070036#include "API.h"
Jean-Marc Valin222494f2011-08-17 15:53:37 -040037#include "stack_alloc.h"
38#include "float_cast.h"
Jean-Marc Valind9920f32011-08-19 13:00:49 -040039#include "opus.h"
40#include "arch.h"
Jean-Marc Valin6696a142011-08-22 10:40:38 -040041#include "opus_private.h"
Jean-Marc Valin07f88402011-08-29 15:08:51 -040042#include "os_support.h"
Jean-Marc Valin222494f2011-08-17 15:53:37 -040043
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070044#include "tuning_parameters.h"
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040045#ifdef FIXED_POINT
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070046#include "fixed/structs_FIX.h"
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040047#else
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070048#include "float/structs_FLP.h"
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040049#endif
50
Jean-Marc Valind9920f32011-08-19 13:00:49 -040051#define MAX_ENCODER_BUFFER 480
52
53struct OpusEncoder {
54 int celt_enc_offset;
55 int silk_enc_offset;
56 silk_EncControlStruct silk_mode;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040057 int application;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040058 int channels;
59 int delay_compensation;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -040060 int force_channels;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040061 int signal_type;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040062 int user_bandwidth;
Jean-Marc Valin9ba17432011-10-24 22:41:18 -040063 int max_bandwidth;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -040064 int user_forced_mode;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040065 int voice_ratio;
Gregory Maxwell64a35412011-09-02 10:31:17 -040066 opus_int32 Fs;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040067 int use_vbr;
68 int vbr_constraint;
Jean-Marc Valin8fdf2af2011-09-10 21:56:34 -040069 opus_int32 bitrate_bps;
70 opus_int32 user_bitrate_bps;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040071 int encoder_buffer;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040072
73#define OPUS_ENCODER_RESET_START stream_channels
74 int stream_channels;
Jean-Marc Valin8fdf2af2011-09-10 21:56:34 -040075 opus_int16 hybrid_stereo_width_Q14;
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040076 opus_int32 variable_HP_smth2_Q15;
77 opus_val32 hp_mem[4];
Jean-Marc Valin927488b2011-08-30 20:09:22 -040078 int mode;
79 int prev_mode;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -040080 int prev_channels;
Gregory Maxwell220a7d42011-10-01 20:30:16 -040081 int prev_framesize;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040082 int bandwidth;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -040083 int silk_bw_switch;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040084 /* Sampling rate (at the API level) */
Jean-Marc Valind9920f32011-08-19 13:00:49 -040085 int first;
86 opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2];
87
Gregory Maxwell64a35412011-09-02 10:31:17 -040088 opus_uint32 rangeFinal;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040089};
90
Jean-Marc Valinc681bd02011-09-02 14:47:26 -040091/* Transition tables for the voice and music. First column is the
Jean-Marc Valin9edde422011-05-05 15:30:44 -040092 middle (memoriless) threshold. The second column is the hysteresis
93 (difference with the middle) */
Jean-Marc Valinc681bd02011-09-02 14:47:26 -040094static const opus_int32 mono_voice_bandwidth_thresholds[8] = {
Ralph Giles04cca282011-08-24 00:29:29 -040095 11000, 1000, /* NB<->MB */
96 14000, 1000, /* MB<->WB */
97 21000, 2000, /* WB<->SWB */
98 29000, 2000, /* SWB<->FB */
Jean-Marc Valin09c67662011-05-04 22:34:53 -040099};
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400100static const opus_int32 mono_music_bandwidth_thresholds[8] = {
101 14000, 1000, /* MB not allowed */
102 18000, 2000, /* MB<->WB */
103 24000, 2000, /* WB<->SWB */
Ralph Giles04cca282011-08-24 00:29:29 -0400104 33000, 2000, /* SWB<->FB */
Jean-Marc Valin09c67662011-05-04 22:34:53 -0400105};
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400106static const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
107 11000, 1000, /* NB<->MB */
108 14000, 1000, /* MB<->WB */
109 21000, 2000, /* WB<->SWB */
110 32000, 2000, /* SWB<->FB */
111};
112static const opus_int32 stereo_music_bandwidth_thresholds[8] = {
113 14000, 1000, /* MB not allowed */
114 18000, 2000, /* MB<->WB */
115 24000, 2000, /* WB<->SWB */
116 48000, 2000, /* SWB<->FB */
117};
118/* Threshold bit-rates for switching between mono and stereo */
119static const opus_int32 stereo_voice_threshold = 26000;
120static const opus_int32 stereo_music_threshold = 36000;
Jean-Marc Valin09c67662011-05-04 22:34:53 -0400121
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400122/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */
123static const opus_int32 mode_thresholds[2][2] = {
124 /* voice */ /* music */
125 { 48000, 24000}, /* mono */
126 { 48000, 24000}, /* stereo */
127};
Jean-Marc Valinb5972382011-10-07 08:38:27 -0400128
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400129int opus_encoder_get_size(int channels)
130{
Ralph Giles641eea82011-08-02 10:06:59 -0700131 int silkEncSizeBytes, celtEncSizeBytes;
132 int ret;
Gregory Maxwellf451b332011-09-04 10:47:15 -0400133 if (channels<1 || channels > 2)
134 return 0;
Ralph Giles641eea82011-08-02 10:06:59 -0700135 ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
Ralph Giles04cca282011-08-24 00:29:29 -0400136 if (ret)
Ralph Giles641eea82011-08-02 10:06:59 -0700137 return 0;
138 silkEncSizeBytes = align(silkEncSizeBytes);
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400139 celtEncSizeBytes = celt_encoder_get_size(channels);
140 return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400141}
142
Gregory Maxwell64a35412011-09-02 10:31:17 -0400143int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application)
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400144{
Ralph Giles641eea82011-08-02 10:06:59 -0700145 void *silk_enc;
146 CELTEncoder *celt_enc;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500147 int err;
Ralph Giles641eea82011-08-02 10:06:59 -0700148 int ret, silkEncSizeBytes;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400149
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400150 if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
151 (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
152 && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400153 return OPUS_BAD_ARG;
Jean-Marc Valind3358b12011-06-14 14:48:53 -0400154
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400155 OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
Jean-Marc Valind3358b12011-06-14 14:48:53 -0400156 /* Create SILK encoder */
157 ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
Ralph Giles04cca282011-08-24 00:29:29 -0400158 if (ret)
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400159 return OPUS_BAD_ARG;
Ralph Giles04cca282011-08-24 00:29:29 -0400160 silkEncSizeBytes = align(silkEncSizeBytes);
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400161 st->silk_enc_offset = align(sizeof(OpusEncoder));
162 st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
Jean-Marc Valin5095c472011-05-05 19:47:48 -0400163 silk_enc = (char*)st+st->silk_enc_offset;
164 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
165
Jean-Marc Valinb3864582011-01-31 12:41:49 -0500166 st->stream_channels = st->channels = channels;
Jean-Marc Valinbcdfe632010-08-31 11:22:43 -0400167
168 st->Fs = Fs;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400169
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400170 ret = silk_InitEncoder( silk_enc, &st->silk_mode );
Gregory Maxwelle03af442011-09-04 04:43:11 -0400171 if(ret)return OPUS_INTERNAL_ERROR;
Jean-Marc Valinae180902010-07-19 11:44:36 -0400172
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500173 /* default SILK parameters */
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400174 st->silk_mode.nChannelsAPI = channels;
175 st->silk_mode.nChannelsInternal = channels;
176 st->silk_mode.API_sampleRate = st->Fs;
177 st->silk_mode.maxInternalSampleRate = 16000;
178 st->silk_mode.minInternalSampleRate = 8000;
179 st->silk_mode.desiredInternalSampleRate = 16000;
180 st->silk_mode.payloadSize_ms = 20;
181 st->silk_mode.bitRate = 25000;
182 st->silk_mode.packetLossPercentage = 0;
183 st->silk_mode.complexity = 10;
184 st->silk_mode.useInBandFEC = 0;
185 st->silk_mode.useDTX = 0;
186 st->silk_mode.useCBR = 0;
187
Jean-Marc Valinc5ea0742010-07-05 11:11:54 -0400188 /* Create CELT encoder */
Ralph Giles641eea82011-08-02 10:06:59 -0700189 /* Initialize CELT encoder */
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400190 err = celt_encoder_init(celt_enc, Fs, channels);
Gregory Maxwelle03af442011-09-04 04:43:11 -0400191 if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR;
192
Jean-Marc Valin5095c472011-05-05 19:47:48 -0400193 celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0));
Jean-Marc Valincdfb8f32011-09-09 14:50:15 -0400194 celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(10));
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400195
Jean-Marc Valin21452882011-09-09 14:57:43 -0400196 st->use_vbr = 1;
Jean-Marc Valin66820f32012-01-31 02:03:39 -0500197 /* Makes constrained VBR the default (safer for real-time use) */
198 st->vbr_constraint = 1;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400199 st->user_bitrate_bps = OPUS_AUTO;
Ralph Giles641eea82011-08-02 10:06:59 -0700200 st->bitrate_bps = 3000+Fs*channels;
Jean-Marc Valin69549ac2011-08-18 17:28:28 -0400201 st->application = application;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400202 st->signal_type = OPUS_AUTO;
203 st->user_bandwidth = OPUS_AUTO;
Jean-Marc Valin9ba17432011-10-24 22:41:18 -0400204 st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400205 st->force_channels = OPUS_AUTO;
206 st->user_forced_mode = OPUS_AUTO;
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400207 st->voice_ratio = -1;
Ralph Giles641eea82011-08-02 10:06:59 -0700208 st->encoder_buffer = st->Fs/100;
Jean-Marc Valin927488b2011-08-30 20:09:22 -0400209
Koen Vosbf75c8e2011-12-13 14:47:31 -0500210 /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead
211 + 1.5 ms for SILK resamplers and stereo prediction) */
212 st->delay_compensation = st->Fs/250;
Jean-Marc Valinb5972382011-10-07 08:38:27 -0400213
Koen Vosbf75c8e2011-12-13 14:47:31 -0500214 st->hybrid_stereo_width_Q14 = 1 << 14;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700215 st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
Jean-Marc Valin927488b2011-08-30 20:09:22 -0400216 st->first = 1;
217 st->mode = MODE_HYBRID;
218 st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
219
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400220 return OPUS_OK;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400221}
222
Gregory Maxwelle7028172011-11-19 23:58:09 -0500223static int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len)
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400224{
225 if (len == new_len)
226 return 0;
227 if (len > new_len)
228 return 1;
229
230 if ((data[0]&0x3)==0)
231 {
232 int i;
233 int padding, nb_255s;
234
235 padding = new_len - len;
236 if (padding >= 2)
237 {
238 nb_255s = (padding-2)/255;
239
240 for (i=len-1;i>=1;i--)
241 data[i+nb_255s+2] = data[i];
242 data[0] |= 0x3;
243 data[1] = 0x41;
244 for (i=0;i<nb_255s;i++)
245 data[i+2] = 255;
246 data[nb_255s+2] = padding-255*nb_255s-2;
247 for (i=len+3+nb_255s;i<new_len;i++)
248 data[i] = 0;
249 } else {
250 for (i=len-1;i>=1;i--)
251 data[i+1] = data[i];
252 data[0] |= 0x3;
253 data[1] = 1;
254 }
255 return 0;
256 } else {
257 return 1;
258 }
259}
260
Jean-Marc Valin78291b22011-10-08 22:12:31 -0400261static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)
Jean-Marc Valin421a6282011-08-18 14:32:16 -0400262{
263 int period;
264 unsigned char toc;
265 period = 0;
266 while (framerate < 400)
267 {
268 framerate <<= 1;
269 period++;
270 }
271 if (mode == MODE_SILK_ONLY)
272 {
Jean-Marc Valin78291b22011-10-08 22:12:31 -0400273 toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5;
Jean-Marc Valin421a6282011-08-18 14:32:16 -0400274 toc |= (period-2)<<3;
275 } else if (mode == MODE_CELT_ONLY)
276 {
277 int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND;
278 if (tmp < 0)
279 tmp = 0;
280 toc = 0x80;
281 toc |= tmp << 5;
282 toc |= period<<3;
283 } else /* Hybrid */
284 {
285 toc = 0x60;
286 toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4;
287 toc |= (period-2)<<3;
288 }
289 toc |= (channels==2)<<2;
290 return toc;
291}
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400292
293#ifndef FIXED_POINT
294void silk_biquad_float(
295 const opus_val16 *in, /* I: Input signal */
296 const opus_int32 *B_Q28, /* I: MA coefficients [3] */
297 const opus_int32 *A_Q28, /* I: AR coefficients [2] */
298 opus_val32 *S, /* I/O: State vector [2] */
299 opus_val16 *out, /* O: Output signal */
300 const opus_int32 len, /* I: Signal length (must be even) */
301 int stride
302)
303{
304 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
305 opus_int k;
306 opus_val32 vout;
307 opus_val32 inval;
308 opus_val32 A[2], B[3];
309
Gregory Maxwell37f56592012-07-17 17:40:55 -0400310 A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28)));
311 A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28)));
312 B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28)));
313 B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28)));
314 B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28)));
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400315
316 /* Negate A_Q28 values and split in two parts */
317
318 for( k = 0; k < len; k++ ) {
319 /* S[ 0 ], S[ 1 ]: Q12 */
320 inval = in[ k*stride ];
321 vout = S[ 0 ] + B[0]*inval;
322
323 S[ 0 ] = S[1] - vout*A[0] + B[1]*inval;
324
325 S[ 1 ] = - vout*A[1] + B[2]*inval;
326
327 /* Scale back to Q0 and saturate */
328 out[ k*stride ] = vout;
329 }
330}
331#endif
332
333static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
334{
335 opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];
336 opus_int32 Fc_Q19, r_Q28, r_Q22;
337
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700338 silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) );
339 Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 );
340 silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400341
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700342 r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400343
344 /* b = r * [ 1; -2; 1 ]; */
345 /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */
346 B_Q28[ 0 ] = r_Q28;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700347 B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400348 B_Q28[ 2 ] = r_Q28;
349
350 /* -r * ( 2 - Fc * Fc ); */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700351 r_Q22 = silk_RSHIFT( r_Q28, 6 );
352 A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) );
353 A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400354
355#ifdef FIXED_POINT
356 silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels );
357 if( channels == 2 ) {
358 silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
359 }
360#else
361 silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );
362 if( channels == 2 ) {
363 silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
364 }
365#endif
366}
367
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -0400368static void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
Jean-Marc Valin37d9e132012-07-11 15:53:39 -0400369 int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -0400370{
371 int i;
Jean-Marc Valin37d9e132012-07-11 15:53:39 -0400372 int overlap;
373 int inc;
374 inc = 48000/Fs;
375 overlap=overlap48/inc;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -0400376 g1 = Q15ONE-g1;
377 g2 = Q15ONE-g2;
378 for (i=0;i<overlap;i++)
379 {
380 opus_val32 diff;
381 opus_val16 g, w;
382 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
383 g = SHR32(MAC16_16(MULT16_16(w,g2),
384 Q15ONE-w, g1), 15);
385 diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
386 diff = MULT16_16_Q15(g, diff);
387 out[i*channels] = out[i*channels] - diff;
388 out[i*channels+1] = out[i*channels+1] + diff;
389 }
390 for (;i<frame_size;i++)
391 {
392 opus_val32 diff;
393 diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
394 diff = MULT16_16_Q15(g2, diff);
395 out[i*channels] = out[i*channels] - diff;
396 out[i*channels+1] = out[i*channels+1] + diff;
397 }
398}
399
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400400OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400401{
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400402 int ret;
Gregory Maxwelle98f1f52011-10-05 01:59:28 -0400403 OpusEncoder *st;
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400404 if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
405 (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
406 && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
407 {
408 if (error)
409 *error = OPUS_BAD_ARG;
410 return NULL;
411 }
Gregory Maxwelle98f1f52011-10-05 01:59:28 -0400412 st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
Jean-Marc Valin85b8e622011-08-29 16:10:08 -0400413 if (st == NULL)
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400414 {
415 if (error)
416 *error = OPUS_ALLOC_FAIL;
417 return NULL;
418 }
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400419 ret = opus_encoder_init(st, Fs, channels, application);
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400420 if (error)
421 *error = ret;
422 if (ret != OPUS_OK)
423 {
Jean-Marc Valin85b8e622011-08-29 16:10:08 -0400424 opus_free(st);
425 st = NULL;
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400426 }
Jean-Marc Valin85b8e622011-08-29 16:10:08 -0400427 return st;
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400428}
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400429
430static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int max_data_bytes)
431{
432 if(!frame_size)frame_size=st->Fs/400;
433 if (st->user_bitrate_bps==OPUS_AUTO)
434 return 60*st->Fs/frame_size + st->Fs*st->channels;
435 else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
436 return max_data_bytes*8*st->Fs/frame_size;
437 else
438 return st->user_bitrate_bps;
439}
440
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400441#ifdef FIXED_POINT
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400442#define opus_encode_native opus_encode
Jean-Marc Valin24ed4652012-05-18 15:14:17 -0400443opus_int32 opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
Gregory Maxwelle7028172011-11-19 23:58:09 -0500444 unsigned char *data, opus_int32 out_data_bytes)
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400445#else
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400446#define opus_encode_native opus_encode_float
Jean-Marc Valin59354a72012-03-08 12:19:07 -0500447opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
Gregory Maxwelle7028172011-11-19 23:58:09 -0500448 unsigned char *data, opus_int32 out_data_bytes)
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400449#endif
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400450{
Ralph Giles641eea82011-08-02 10:06:59 -0700451 void *silk_enc;
452 CELTEncoder *celt_enc;
Jean-Marc Valine2d1ef12010-07-06 15:39:19 -0400453 int i;
Ralph Giles641eea82011-08-02 10:06:59 -0700454 int ret=0;
Jean-Marc Valin59354a72012-03-08 12:19:07 -0500455 opus_int32 nBytes;
Ralph Giles641eea82011-08-02 10:06:59 -0700456 ec_enc enc;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500457 int bytes_target;
Jean-Marc Valine3de5052011-02-20 12:23:48 -0500458 int prefill=0;
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -0500459 int start_band = 0;
Jean-Marc Valine2a09db2011-03-02 17:54:43 -0500460 int redundancy = 0;
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -0500461 int redundancy_bytes = 0;
462 int celt_to_silk = 0;
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400463 VARDECL(opus_val16, pcm_buf);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -0500464 int nb_compr_bytes;
465 int to_celt = 0;
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -0400466 opus_uint32 redundant_rng = 0;
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400467 int cutoff_Hz, hp_freq_smth1;
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400468 int voice_est;
469 opus_int32 equiv_rate;
Jean-Marc Valind186c912011-09-08 15:13:46 -0400470 int delay_compensation;
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400471 int frame_rate;
472 opus_int32 max_rate;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400473 int curr_bandwidth;
Gregory Maxwelle7028172011-11-19 23:58:09 -0500474 opus_int32 max_data_bytes;
Jean-Marc Valine22cc272011-10-14 13:48:17 -0400475 VARDECL(opus_val16, tmp_prefill);
476
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400477 ALLOC_STACK;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500478
Gregory Maxwelle7028172011-11-19 23:58:09 -0500479 max_data_bytes = IMIN(1276, out_data_bytes);
Jean-Marc Valin904e7a82011-09-11 14:29:46 -0400480
Jean-Marc Valin2b98bdf2011-08-20 00:21:46 -0400481 st->rangeFinal = 0;
Jean-Marc Valin23a900c2011-06-14 14:34:02 -0400482 if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
483 50*frame_size != st->Fs && 25*frame_size != st->Fs && 50*frame_size != 3*st->Fs)
Jean-Marc Valin44e27dd2011-08-29 23:35:17 -0400484 {
485 RESTORE_STACK;
486 return OPUS_BAD_ARG;
487 }
Jean-Marc Valin5609cec2011-12-13 14:52:43 -0500488 if (max_data_bytes<=0)
489 {
490 RESTORE_STACK;
491 return OPUS_BAD_ARG;
492 }
Jean-Marc Valin5095c472011-05-05 19:47:48 -0400493 silk_enc = (char*)st+st->silk_enc_offset;
494 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
Jean-Marc Valinba547462011-05-10 17:54:41 -0400495
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -0400496 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
Jean-Marc Valind186c912011-09-08 15:13:46 -0400497 delay_compensation = 0;
498 else
499 delay_compensation = st->delay_compensation;
500
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400501 st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
Jean-Marc Valinba547462011-05-10 17:54:41 -0400502
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400503 frame_rate = st->Fs/frame_size;
Jean-Marc Valin5609cec2011-12-13 14:52:43 -0500504 if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
505 || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
506 {
507 int tocmode = st->mode;
508 if (tocmode==0)
509 tocmode = MODE_SILK_ONLY;
510 if (frame_rate>100)
511 tocmode = MODE_CELT_ONLY;
512 if (frame_rate < 50)
513 tocmode = MODE_SILK_ONLY;
514 data[0] = gen_toc(tocmode, frame_rate,
515 st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth,
516 st->stream_channels);
517 RESTORE_STACK;
518 return 1;
519 }
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400520 if (!st->use_vbr)
521 {
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400522 int cbrBytes;
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400523 cbrBytes = IMIN( (st->bitrate_bps + 4*frame_rate)/(8*frame_rate) , max_data_bytes);
524 st->bitrate_bps = cbrBytes * (8*frame_rate);
525 max_data_bytes = cbrBytes;
526 }
Koen Vos43a0de42011-10-24 09:10:58 -0400527 max_rate = frame_rate*max_data_bytes*8;
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400528
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400529 /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
530 equiv_rate = st->bitrate_bps - 60*(st->Fs/frame_size - 50);
531
532 if (st->signal_type == OPUS_SIGNAL_VOICE)
533 voice_est = 127;
534 else if (st->signal_type == OPUS_SIGNAL_MUSIC)
535 voice_est = 0;
536 else if (st->voice_ratio >= 0)
537 voice_est = st->voice_ratio*327>>8;
538 else if (st->application == OPUS_APPLICATION_VOIP)
539 voice_est = 115;
540 else
Jean-Marc Valin9dc0e402011-10-24 20:26:29 -0400541 voice_est = 48;
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400542
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400543 if (st->force_channels!=OPUS_AUTO && st->channels == 2)
Koen Vos479e18b2011-05-25 23:09:52 -0400544 {
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400545 st->stream_channels = st->force_channels;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500546 } else {
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400547#ifdef FUZZING
548 /* Random mono/stereo decision */
549 if (st->channels == 2 && (rand()&0x1F)==0)
550 st->stream_channels = 3-st->stream_channels;
551#else
552 /* Rate-dependent mono-stereo decision */
553 if (st->channels == 2)
554 {
555 opus_int32 stereo_threshold;
556 stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14);
557 if (st->stream_channels == 2)
558 stereo_threshold -= 4000;
559 else
560 stereo_threshold += 4000;
561 st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1;
562 } else {
563 st->stream_channels = st->channels;
564 }
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400565#endif
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400566 }
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400567
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -0400568 /* Mode selection depending on application and signal type */
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -0400569 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
Jean-Marc Valind186c912011-09-08 15:13:46 -0400570 {
571 st->mode = MODE_CELT_ONLY;
572 } else if (st->user_forced_mode == OPUS_AUTO)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500573 {
Jean-Marc Valin9fd13d62011-10-07 22:50:49 -0400574#ifdef FUZZING
575 /* Random mode switching */
576 if ((rand()&0xF)==0)
577 {
578 if ((rand()&0x1)==0)
579 st->mode = MODE_CELT_ONLY;
580 else
581 st->mode = MODE_SILK_ONLY;
582 } else {
583 if (st->prev_mode==MODE_CELT_ONLY)
584 st->mode = MODE_CELT_ONLY;
585 else
586 st->mode = MODE_SILK_ONLY;
587 }
588#else
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400589 int chan;
590 opus_int32 mode_voice, mode_music;
591 opus_int32 threshold;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500592
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400593 chan = (st->channels==2) && st->force_channels!=1;
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400594 mode_voice = mode_thresholds[chan][0];
595 mode_music = mode_thresholds[chan][1];
596 threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14);
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -0400597
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400598 /* Hysteresis */
599 if (st->prev_mode == MODE_CELT_ONLY)
600 threshold -= 4000;
601 else if (st->prev_mode>0)
602 threshold += 4000;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -0400603
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400604 st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY;
Jean-Marc Valin9dc0e402011-10-24 20:26:29 -0400605
Jean-Marc Valin6ef37872011-10-27 13:39:12 -0400606 /* When FEC is enabled and there's enough packet loss, use SILK */
Jean-Marc Valin9dc0e402011-10-24 20:26:29 -0400607 if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)
608 st->mode = MODE_SILK_ONLY;
Jean-Marc Valin6ef37872011-10-27 13:39:12 -0400609 /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */
610 if (st->silk_mode.useDTX && voice_est > 100)
611 st->mode = MODE_SILK_ONLY;
Jean-Marc Valin9fd13d62011-10-07 22:50:49 -0400612#endif
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400613 } else {
614 st->mode = st->user_forced_mode;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -0400615 }
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400616
Jean-Marc Valin81936d52011-08-13 01:44:39 -0400617 /* Override the chosen mode to make sure we meet the requested frame size */
Jean-Marc Valin81936d52011-08-13 01:44:39 -0400618 if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100)
619 st->mode = MODE_CELT_ONLY;
620
Jean-Marc Valin9fd13d62011-10-07 22:50:49 -0400621 if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
622 && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
623 {
624 /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
625 st->silk_mode.toMono = 1;
626 st->stream_channels = 2;
627 } else {
628 st->silk_mode.toMono = 0;
629 }
630
Jean-Marc Valin68545562011-08-12 00:30:47 -0400631 if (st->prev_mode > 0 &&
632 ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
633 (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
634 {
635 redundancy = 1;
636 celt_to_silk = (st->mode != MODE_CELT_ONLY);
637 if (!celt_to_silk)
638 {
639 /* Switch to SILK/hybrid if frame size is 10 ms or more*/
640 if (frame_size >= st->Fs/100)
641 {
642 st->mode = st->prev_mode;
643 to_celt = 1;
644 } else {
645 redundancy=0;
646 }
647 }
648 }
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400649 if (st->silk_bw_switch)
650 {
651 redundancy = 1;
652 celt_to_silk = 1;
653 st->silk_bw_switch = 0;
654 }
655
Jean-Marc Valin68545562011-08-12 00:30:47 -0400656 if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
657 {
658 silk_EncControlStruct dummy;
659 silk_InitEncoder( silk_enc, &dummy);
660 prefill=1;
661 }
662
Jean-Marc Valin243ff0c2011-05-03 17:06:54 -0400663 /* Automatic (rate-dependent) bandwidth selection */
Jean-Marc Valin09c67662011-05-04 22:34:53 -0400664 if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500665 {
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400666 const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;
667 opus_int32 bandwidth_thresholds[8];
Ralph Giles641eea82011-08-02 10:06:59 -0700668 int bandwidth = OPUS_BANDWIDTH_FULLBAND;
Jean-Marc Valinbfad2812011-10-25 13:46:35 -0400669 opus_int32 equiv_rate2;
Jean-Marc Valin09c67662011-05-04 22:34:53 -0400670
Jean-Marc Valinbfad2812011-10-25 13:46:35 -0400671 equiv_rate2 = equiv_rate;
672 if (st->mode != MODE_CELT_ONLY)
673 {
674 /* Adjust the threshold +/- 10% depending on complexity */
675 equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50;
676 /* CBR is less efficient by ~1 kb/s */
677 if (!st->use_vbr)
678 equiv_rate2 -= 1000;
679 }
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400680 if (st->channels==2 && st->force_channels!=1)
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400681 {
682 voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
683 music_bandwidth_thresholds = stereo_music_bandwidth_thresholds;
684 } else {
685 voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds;
686 music_bandwidth_thresholds = mono_music_bandwidth_thresholds;
687 }
688 /* Interpolate bandwidth thresholds depending on voice estimation */
689 for (i=0;i<8;i++)
690 {
691 bandwidth_thresholds[i] = music_bandwidth_thresholds[i]
692 + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14);
693 }
Ralph Giles641eea82011-08-02 10:06:59 -0700694 do {
695 int threshold, hysteresis;
696 threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)];
697 hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1];
698 if (!st->first)
699 {
700 if (st->bandwidth >= bandwidth)
701 threshold -= hysteresis;
702 else
703 threshold += hysteresis;
704 }
Jean-Marc Valinbfad2812011-10-25 13:46:35 -0400705 if (equiv_rate2 >= threshold)
Ralph Giles641eea82011-08-02 10:06:59 -0700706 break;
707 } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
708 st->bandwidth = bandwidth;
709 /* Prevents any transition to SWB/FB until the SILK layer has fully
710 switched to WB mode and turned the variable LP filter off */
Jean-Marc Valine1be1922011-11-28 22:48:01 -0500711 if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
Ralph Giles641eea82011-08-02 10:06:59 -0700712 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500713 }
Jean-Marc Valin955f94c2011-03-08 22:12:43 -0500714
Jean-Marc Valin9ba17432011-10-24 22:41:18 -0400715 if (st->bandwidth>st->max_bandwidth)
716 st->bandwidth = st->max_bandwidth;
717
Jean-Marc Valinefe16c52011-09-29 22:02:37 -0400718 if (st->user_bandwidth != OPUS_AUTO)
719 st->bandwidth = st->user_bandwidth;
720
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400721 /* This prevents us from using hybrid at unsafe CBR/max rates */
722 if (st->mode != MODE_CELT_ONLY && max_rate < 15000)
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400723 {
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400724 st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND);
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400725 }
726
Jean-Marc Valin243ff0c2011-05-03 17:06:54 -0400727 /* Prevents Opus from wasting bits on frequencies that are above
728 the Nyquist rate of the input signal */
Jean-Marc Valin541df0a2011-05-26 00:22:58 -0400729 if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND)
Ralph Giles641eea82011-08-02 10:06:59 -0700730 st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -0400731 if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
Ralph Giles641eea82011-08-02 10:06:59 -0700732 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -0400733 if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND)
Ralph Giles641eea82011-08-02 10:06:59 -0700734 st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -0400735 if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND)
Ralph Giles641eea82011-08-02 10:06:59 -0700736 st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
Jean-Marc Valin955f94c2011-03-08 22:12:43 -0500737
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400738 /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -0400739 if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8))
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400740 st->mode = MODE_CELT_ONLY;
Jean-Marc Valin955f94c2011-03-08 22:12:43 -0500741
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400742 /* CELT mode doesn't support mediumband, use wideband instead */
743 if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
744 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
745
Jean-Marc Valin81936d52011-08-13 01:44:39 -0400746 /* Can't support higher than wideband for >20 ms frames */
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400747 if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND))
748 {
Jean-Marc Valind970a852011-09-08 21:41:29 -0400749 VARDECL(unsigned char, tmp_data);
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400750 int nb_frames;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400751 int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
Jean-Marc Valinc8649d02011-10-27 22:25:33 -0400752 OpusRepacketizer rp;
Gregory Maxwelle7028172011-11-19 23:58:09 -0500753 opus_int32 bytes_per_frame;
Jean-Marc Valind970a852011-09-08 21:41:29 -0400754
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400755
Jean-Marc Valind970a852011-09-08 21:41:29 -0400756 nb_frames = frame_size > st->Fs/25 ? 3 : 2;
Gregory Maxwelle7028172011-11-19 23:58:09 -0500757 bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);
Jean-Marc Valind970a852011-09-08 21:41:29 -0400758
759 ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
Jean-Marc Valind970a852011-09-08 21:41:29 -0400760
Jean-Marc Valinc8649d02011-10-27 22:25:33 -0400761 opus_repacketizer_init(&rp);
Jean-Marc Valind3358b12011-06-14 14:48:53 -0400762
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400763 bak_mode = st->user_forced_mode;
764 bak_bandwidth = st->user_bandwidth;
765 bak_channels = st->force_channels;
766
767 st->user_forced_mode = st->mode;
768 st->user_bandwidth = st->bandwidth;
769 st->force_channels = st->stream_channels;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400770 bak_to_mono = st->silk_mode.toMono;
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400771
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400772 if (bak_to_mono)
773 st->force_channels = 1;
774 else
775 st->prev_channels = st->stream_channels;
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400776 for (i=0;i<nb_frames;i++)
777 {
778 int tmp_len;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400779 st->silk_mode.toMono = 0;
Jean-Marc Valin7ef6c7c2011-10-17 14:20:43 -0400780 /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
781 if (to_celt && i==nb_frames-1)
782 st->user_forced_mode = MODE_CELT_ONLY;
Jean-Marc Valind970a852011-09-08 21:41:29 -0400783 tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50, tmp_data+i*bytes_per_frame, bytes_per_frame);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -0400784 if (tmp_len<0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -0500785 {
786 RESTORE_STACK;
Jean-Marc Valinf340bba2011-10-27 20:33:48 -0400787 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -0500788 }
Jean-Marc Valinc8649d02011-10-27 22:25:33 -0400789 ret = opus_repacketizer_cat(&rp, tmp_data+i*bytes_per_frame, tmp_len);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -0400790 if (ret<0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -0500791 {
792 RESTORE_STACK;
Jean-Marc Valinf340bba2011-10-27 20:33:48 -0400793 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -0500794 }
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400795 }
Gregory Maxwelle7028172011-11-19 23:58:09 -0500796 ret = opus_repacketizer_out(&rp, data, out_data_bytes);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -0400797 if (ret<0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -0500798 {
799 RESTORE_STACK;
Jean-Marc Valinf340bba2011-10-27 20:33:48 -0400800 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -0500801 }
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400802 st->user_forced_mode = bak_mode;
803 st->user_bandwidth = bak_bandwidth;
804 st->force_channels = bak_channels;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -0400805 st->silk_mode.toMono = bak_to_mono;
Jean-Marc Valine4336a52011-09-08 18:19:50 -0400806 RESTORE_STACK;
807 return ret;
808 }
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400809
810 curr_bandwidth = st->bandwidth;
Jean-Marc Valin81936d52011-08-13 01:44:39 -0400811
812 /* Chooses the appropriate mode for speech
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400813 *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400814 if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500815 st->mode = MODE_HYBRID;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400816 if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500817 st->mode = MODE_SILK_ONLY;
818
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400819 /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
Jean-Marc Valine1be1922011-11-28 22:48:01 -0500820 bytes_target = IMIN(max_data_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500821
Ralph Giles641eea82011-08-02 10:06:59 -0700822 data += 1;
Jean-Marc Valin606250a2011-02-15 14:31:21 -0500823
Ralph Giles641eea82011-08-02 10:06:59 -0700824 ec_enc_init(&enc, data, max_data_bytes-1);
Jean-Marc Valin24af3032010-06-30 14:29:45 -0400825
Jean-Marc Valind186c912011-09-08 15:13:46 -0400826 ALLOC(pcm_buf, (delay_compensation+frame_size)*st->channels, opus_val16);
827 for (i=0;i<delay_compensation*st->channels;i++)
828 pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-delay_compensation)*st->channels+i];
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400829
830 if (st->mode == MODE_CELT_ONLY)
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700831 hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400832 else
833 hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15;
834
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700835 st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15,
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400836 hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) );
837
838 /* convert from log scale to Hertz */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700839 cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400840
841 if (st->application == OPUS_APPLICATION_VOIP)
842 {
Jean-Marc Valind186c912011-09-08 15:13:46 -0400843 hp_cutoff(pcm, cutoff_Hz, &pcm_buf[delay_compensation*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400844 } else {
845 for (i=0;i<frame_size*st->channels;i++)
Jean-Marc Valind186c912011-09-08 15:13:46 -0400846 pcm_buf[delay_compensation*st->channels + i] = pcm[i];
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400847 }
Jean-Marc Valin2f0ca762011-09-01 16:56:40 -0400848
Ralph Giles641eea82011-08-02 10:06:59 -0700849 /* SILK processing */
Jean-Marc Valin606250a2011-02-15 14:31:21 -0500850 if (st->mode != MODE_CELT_ONLY)
851 {
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400852#ifdef FIXED_POINT
853 const opus_int16 *pcm_silk;
854#else
855 VARDECL(opus_int16, pcm_silk);
856 ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
857#endif
Jean-Marc Valincb9471c2011-10-27 16:45:45 -0400858 st->silk_mode.bitRate = 8*bytes_target*frame_rate;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500859 if( st->mode == MODE_HYBRID ) {
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400860 st->silk_mode.bitRate /= st->stream_channels;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400861 if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {
Karsten Vandborg Sorensen78054752011-02-03 09:36:59 -0500862 if( st->Fs == 100 * frame_size ) {
863 /* 24 kHz, 10 ms */
Koen Vos5ad41a32011-02-04 00:49:48 -0500864 st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3;
Karsten Vandborg Sorensen78054752011-02-03 09:36:59 -0500865 } else {
866 /* 24 kHz, 20 ms */
Koen Vos5ad41a32011-02-04 00:49:48 -0500867 st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3;
Karsten Vandborg Sorensen78054752011-02-03 09:36:59 -0500868 }
869 } else {
870 if( st->Fs == 100 * frame_size ) {
871 /* 48 kHz, 10 ms */
Koen Vos5ad41a32011-02-04 00:49:48 -0500872 st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2;
Karsten Vandborg Sorensen78054752011-02-03 09:36:59 -0500873 } else {
874 /* 48 kHz, 20 ms */
Koen Vos5ad41a32011-02-04 00:49:48 -0500875 st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2;
Karsten Vandborg Sorensen78054752011-02-03 09:36:59 -0500876 }
877 }
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400878 st->silk_mode.bitRate *= st->stream_channels;
Koen Vos03c1d662011-02-17 16:54:44 -0500879 /* don't let SILK use more than 80% */
880 if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) {
881 st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5;
882 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500883 }
Jean-Marc Valin862e1822010-07-20 12:19:00 -0400884
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500885 st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400886 st->silk_mode.nChannelsAPI = st->channels;
887 st->silk_mode.nChannelsInternal = st->stream_channels;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400888 if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
Ralph Giles641eea82011-08-02 10:06:59 -0700889 st->silk_mode.desiredInternalSampleRate = 8000;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400890 } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
Ralph Giles641eea82011-08-02 10:06:59 -0700891 st->silk_mode.desiredInternalSampleRate = 12000;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500892 } else {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400893 silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
Jean-Marc Valind8f90972011-04-27 10:06:53 -0400894 st->silk_mode.desiredInternalSampleRate = 16000;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500895 }
896 if( st->mode == MODE_HYBRID ) {
897 /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
Koen Vos1e1562c2011-02-14 15:04:59 -0500898 st->silk_mode.minInternalSampleRate = 16000;
899 } else {
900 st->silk_mode.minInternalSampleRate = 8000;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500901 }
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400902
903 if (st->mode == MODE_SILK_ONLY)
904 {
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -0400905 opus_int32 effective_max_rate = max_rate;
Jean-Marc Valine1be1922011-11-28 22:48:01 -0500906 st->silk_mode.maxInternalSampleRate = 16000;
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -0400907 if (frame_rate > 50)
908 effective_max_rate = effective_max_rate*2/3;
909 if (effective_max_rate < 13000)
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400910 {
911 st->silk_mode.maxInternalSampleRate = 12000;
912 st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate);
913 }
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -0400914 if (effective_max_rate < 9600)
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400915 {
916 st->silk_mode.maxInternalSampleRate = 8000;
917 st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate);
918 }
919 } else {
920 st->silk_mode.maxInternalSampleRate = 16000;
921 }
Jean-Marc Valinb5be8262010-11-12 06:47:46 +0800922
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400923 st->silk_mode.useCBR = !st->use_vbr;
924
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500925 /* Call SILK encoder for the low band */
Jean-Marc Valin66c612e2011-08-15 14:08:57 -0400926 nBytes = IMIN(1275, max_data_bytes-1);
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400927
928 st->silk_mode.maxBits = nBytes*8;
929 /* Only allow up to 90% of the bits for hybrid mode*/
930 if (st->mode == MODE_HYBRID)
931 st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10;
932 if (st->silk_mode.useCBR)
933 {
934 st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8;
935 /* Reduce the initial target to make it easier to reach the CBR rate */
Jean-Marc Valind17bc2e2011-10-27 16:46:34 -0400936 st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);
Jean-Marc Valin294bfec2011-10-20 00:39:41 -0400937 }
938 if (redundancy)
939 st->silk_mode.maxBits -= st->silk_mode.maxBits/(1 + frame_size/(st->Fs/200));
940
Jean-Marc Valine3de5052011-02-20 12:23:48 -0500941 if (prefill)
Jean-Marc Valina93f5012011-03-03 15:50:08 -0500942 {
Jean-Marc Valin59354a72012-03-08 12:19:07 -0500943 opus_int32 zero=0;
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400944#ifdef FIXED_POINT
945 pcm_silk = st->delay_buffer;
946#else
947 for (i=0;i<st->encoder_buffer*st->channels;i++)
Ralph Giles04cca282011-08-24 00:29:29 -0400948 pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400949#endif
950 silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 );
Jean-Marc Valina93f5012011-03-03 15:50:08 -0500951 }
Jean-Marc Valine3de5052011-02-20 12:23:48 -0500952
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400953#ifdef FIXED_POINT
Jean-Marc Valind186c912011-09-08 15:13:46 -0400954 pcm_silk = pcm_buf+delay_compensation*st->channels;
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400955#else
956 for (i=0;i<frame_size*st->channels;i++)
Jean-Marc Valind186c912011-09-08 15:13:46 -0400957 pcm_silk[i] = FLOAT2INT16(pcm_buf[delay_compensation*st->channels + i]);
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400958#endif
959 ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500960 if( ret ) {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400961 /*fprintf (stderr, "SILK encode error: %d\n", ret);*/
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500962 /* Handle error */
Jean-Marc Valinc7921082012-03-05 19:56:13 -0500963 RESTORE_STACK;
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400964 return OPUS_INTERNAL_ERROR;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500965 }
Jean-Marc Valin617fcd22011-03-16 22:11:53 -0400966 if (nBytes==0)
Jean-Marc Valin421a6282011-08-18 14:32:16 -0400967 {
Jean-Marc Valine1be1922011-11-28 22:48:01 -0500968 st->rangeFinal = 0;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400969 data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
Jean-Marc Valin44e27dd2011-08-29 23:35:17 -0400970 RESTORE_STACK;
Jean-Marc Valin421a6282011-08-18 14:32:16 -0400971 return 1;
972 }
Jean-Marc Valin69bfc672011-08-29 21:46:17 -0400973 /* Extract SILK internal bandwidth for signaling in first byte */
974 if( st->mode == MODE_SILK_ONLY ) {
975 if( st->silk_mode.internalSampleRate == 8000 ) {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400976 curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
Jean-Marc Valin69bfc672011-08-29 21:46:17 -0400977 } else if( st->silk_mode.internalSampleRate == 12000 ) {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400978 curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
Jean-Marc Valin69bfc672011-08-29 21:46:17 -0400979 } else if( st->silk_mode.internalSampleRate == 16000 ) {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400980 curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valin69bfc672011-08-29 21:46:17 -0400981 }
982 } else {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700983 silk_assert( st->silk_mode.internalSampleRate == 16000 );
Jean-Marc Valin69bfc672011-08-29 21:46:17 -0400984 }
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400985
986 st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
987 if (st->silk_mode.opusCanSwitch)
988 {
989 redundancy = 1;
990 celt_to_silk = 0;
991 st->silk_bw_switch = 1;
992 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500993 }
Jean-Marc Valin67008d22010-07-20 11:13:30 -0400994
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500995 /* CELT processing */
Ralph Giles641eea82011-08-02 10:06:59 -0700996 {
997 int endband=21;
Jean-Marc Valine2d1ef12010-07-06 15:39:19 -0400998
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400999 switch(curr_bandwidth)
Ralph Giles641eea82011-08-02 10:06:59 -07001000 {
1001 case OPUS_BANDWIDTH_NARROWBAND:
1002 endband = 13;
1003 break;
1004 case OPUS_BANDWIDTH_MEDIUMBAND:
Ralph Giles04cca282011-08-24 00:29:29 -04001005 case OPUS_BANDWIDTH_WIDEBAND:
1006 endband = 17;
1007 break;
Ralph Giles641eea82011-08-02 10:06:59 -07001008 case OPUS_BANDWIDTH_SUPERWIDEBAND:
1009 endband = 19;
1010 break;
1011 case OPUS_BANDWIDTH_FULLBAND:
1012 endband = 21;
1013 break;
1014 }
1015 celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband));
1016 celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels));
1017 }
Jean-Marc Valin23f3a1f2011-10-30 22:41:32 -04001018 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
Ralph Giles641eea82011-08-02 10:06:59 -07001019 if (st->mode != MODE_SILK_ONLY)
1020 {
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001021 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001022 /* Allow prediction unless we decide to disable it later */
1023 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2));
Jean-Marc Valine2a09db2011-03-02 17:54:43 -05001024
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001025 if (st->mode == MODE_HYBRID)
1026 {
1027 int len;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001028
Timothy B. Terriberrya1dd0fc2011-02-03 14:52:50 -08001029 len = (ec_tell(&enc)+7)>>3;
Jean-Marc Valin6d5af482011-10-08 22:45:19 -04001030 if (redundancy)
1031 len += st->mode == MODE_HYBRID ? 3 : 1;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001032 if( st->use_vbr ) {
Koen Vos5ad41a32011-02-04 00:49:48 -05001033 nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001034 } else {
1035 /* check if SILK used up too much */
1036 nb_compr_bytes = len > bytes_target ? len : bytes_target;
1037 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001038 } else {
Jean-Marc Valind9ad6e12011-02-01 18:08:41 -05001039 if (st->use_vbr)
1040 {
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001041 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
1042 celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
1043 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps));
Jean-Marc Valind9ad6e12011-02-01 18:08:41 -05001044 nb_compr_bytes = max_data_bytes-1;
1045 } else {
1046 nb_compr_bytes = bytes_target;
1047 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001048 }
1049
Ralph Giles641eea82011-08-02 10:06:59 -07001050 } else {
1051 nb_compr_bytes = 0;
1052 }
Jean-Marc Valinc8a20b72010-07-21 14:07:11 -04001053
Jean-Marc Valine22cc272011-10-14 13:48:17 -04001054 ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001055 if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0)
Jean-Marc Valine22cc272011-10-14 13:48:17 -04001056 {
1057 for (i=0;i<st->channels*st->Fs/400;i++)
1058 tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels + i];
1059 }
1060
Jean-Marc Valind186c912011-09-08 15:13:46 -04001061 for (i=0;i<st->channels*(st->encoder_buffer-(frame_size+delay_compensation));i++)
Jean-Marc Valin12c39922011-09-04 11:00:29 -04001062 st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size];
1063 for (;i<st->encoder_buffer*st->channels;i++)
Jean-Marc Valind186c912011-09-08 15:13:46 -04001064 st->delay_buffer[i] = pcm_buf[(frame_size+delay_compensation-st->encoder_buffer)*st->channels+i];
Jean-Marc Valin2f0ca762011-09-01 16:56:40 -04001065
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001066
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001067 if (st->mode != MODE_HYBRID || st->stream_channels==1)
Jean-Marc Valinebece632011-10-09 00:29:26 -04001068 st->silk_mode.stereoWidth_Q14 = 1<<14;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001069 if( st->channels == 2 ) {
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001070 /* Apply stereo width reduction (at low bitrates) */
1071 if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001072 opus_val16 g1, g2;
1073 const CELTMode *celt_mode;
1074
1075 celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode));
1076 g1 = st->hybrid_stereo_width_Q14;
Koen Vos854fe702011-10-09 20:34:41 -04001077 g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14);
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001078#ifdef FIXED_POINT
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001079 g1 = g1==16384 ? Q15ONE : SHL16(g1,1);
1080 g2 = g2==16384 ? Q15ONE : SHL16(g2,1);
Jean-Marc Valinab964572011-10-13 16:18:24 -04001081#else
Gregory Maxwell37f56592012-07-17 17:40:55 -04001082 g1 *= (1.f/16384);
1083 g2 *= (1.f/16384);
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001084#endif
1085 stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap,
1086 frame_size, st->channels, celt_mode->window, st->Fs);
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001087 st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14;
1088 }
1089 }
1090
Jean-Marc Valine9b53212011-10-13 16:24:11 -04001091 if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1))
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001092 {
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001093 /* For SILK mode, the redundancy is inferred from the length */
Gregory Maxwelld9dd4992011-10-16 04:02:02 -04001094 if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes))
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001095 ec_enc_bit_logp(&enc, redundancy, 12);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001096 if (redundancy)
1097 {
Jean-Marc Valine5736ae2011-09-05 10:28:27 -04001098 int max_redundancy;
1099 ec_enc_bit_logp(&enc, celt_to_silk, 1);
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001100 if (st->mode == MODE_HYBRID)
1101 max_redundancy = (max_data_bytes-1)-nb_compr_bytes-1;
1102 else
1103 max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001104 /* Target the same bit-rate for redundancy as for the rest,
1105 up to a max of 257 bytes */
Jean-Marc Valine5736ae2011-09-05 10:28:27 -04001106 redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600);
1107 redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001108 if (st->mode == MODE_HYBRID)
Ralph Giles04cca282011-08-24 00:29:29 -04001109 ec_enc_uint(&enc, redundancy_bytes-2, 256);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001110 }
Jean-Marc Valine5736ae2011-09-05 10:28:27 -04001111 } else {
1112 redundancy = 0;
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001113 }
1114
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001115 if (!redundancy)
1116 st->silk_bw_switch = 0;
1117
Gregory Maxwell7d1df732011-09-05 11:28:28 -04001118 if (st->mode != MODE_CELT_ONLY)start_band=17;
1119
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001120 if (st->mode == MODE_SILK_ONLY)
1121 {
1122 ret = (ec_tell(&enc)+7)>>3;
1123 ec_enc_done(&enc);
1124 nb_compr_bytes = ret;
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001125 } else {
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001126 nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001127 ec_enc_shrink(&enc, nb_compr_bytes);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001128 }
1129
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001130
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001131 /* 5 ms redundant frame for CELT->SILK */
1132 if (redundancy && celt_to_silk)
1133 {
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001134 int err;
Jean-Marc Valin5095c472011-05-05 19:47:48 -04001135 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001136 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001137 err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
1138 if (err < 0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001139 {
1140 RESTORE_STACK;
1141 return OPUS_INTERNAL_ERROR;
1142 }
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001143 celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
1144 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001145 }
1146
Jean-Marc Valin5095c472011-05-05 19:47:48 -04001147 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001148
1149 if (st->mode != MODE_SILK_ONLY)
Ralph Giles641eea82011-08-02 10:06:59 -07001150 {
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001151 if (st->mode != st->prev_mode && st->prev_mode > 0)
1152 {
1153 unsigned char dummy[2];
1154 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
1155
1156 /* Prefilling */
1157 celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
1158 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
1159 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001160 /* If false, we already busted the budget and we'll end up with a "PLC packet" */
Jean-Marc Valine1be1922011-11-28 22:48:01 -05001161 if (ec_tell(&enc) <= 8*nb_compr_bytes)
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001162 {
1163 ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
1164 if (ret < 0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001165 {
1166 RESTORE_STACK;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001167 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001168 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001169 }
Ralph Giles641eea82011-08-02 10:06:59 -07001170 }
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001171
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001172 /* 5 ms redundant frame for SILK->CELT */
1173 if (redundancy && !celt_to_silk)
1174 {
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001175 int err;
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001176 unsigned char dummy[2];
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001177 int N2, N4;
1178 N2 = st->Fs/200;
1179 N4 = st->Fs/400;
1180
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001181 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
Jean-Marc Valin5095c472011-05-05 19:47:48 -04001182 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
1183 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001184
Jean-Marc Valin92675062011-09-11 22:00:46 -04001185 /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001186 celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001187
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001188 err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL);
1189 if (err < 0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001190 {
1191 RESTORE_STACK;
1192 return OPUS_INTERNAL_ERROR;
1193 }
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001194 celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001195 }
1196
1197
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001198
Ralph Giles641eea82011-08-02 10:06:59 -07001199 /* Signalling the mode in the first byte */
1200 data--;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001201 data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
Jean-Marc Valin57de8a32010-09-07 17:37:56 -04001202
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -04001203 st->rangeFinal = enc.rng ^ redundant_rng;
Ralph Giles3f0962c2011-07-29 14:01:54 -07001204
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001205 if (to_celt)
1206 st->prev_mode = MODE_CELT_ONLY;
1207 else
1208 st->prev_mode = st->mode;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001209 st->prev_channels = st->stream_channels;
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001210 st->prev_framesize = frame_size;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001211
Jean-Marc Valinc1673fa2011-04-28 08:04:20 -04001212 st->first = 0;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001213
1214 /* In the unlikely case that the SILK encoder busted its target, tell
1215 the decoder to call the PLC */
1216 if (ec_tell(&enc) > (max_data_bytes-1)*8)
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001217 {
Vincent Penquerc'h037918a2011-11-22 15:12:44 +00001218 if (max_data_bytes < 2)
1219 {
1220 RESTORE_STACK;
1221 return OPUS_BUFFER_TOO_SMALL;
1222 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001223 data[1] = 0;
1224 ret = 1;
1225 st->rangeFinal = 0;
Jean-Marc Valine1be1922011-11-28 22:48:01 -05001226 } else if (st->mode==MODE_SILK_ONLY&&!redundancy)
1227 {
1228 /*When in LPC only mode it's perfectly
1229 reasonable to strip off trailing zero bytes as
1230 the required range decoder behavior is to
1231 fill these in. This can't be done when the MDCT
1232 modes are used because the decoder needs to know
1233 the actual length for allocation purposes.*/
1234 while(ret>2&&data[ret]==0)ret--;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001235 }
1236 /* Count ToC and redundancy */
1237 ret += 1+redundancy_bytes;
1238 if (!st->use_vbr && ret >= 3)
1239 {
1240 if (pad_frame(data, ret, max_data_bytes))
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001241 {
1242 RESTORE_STACK;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001243 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001244 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001245 ret = max_data_bytes;
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001246 }
Jean-Marc Valin44e27dd2011-08-29 23:35:17 -04001247 RESTORE_STACK;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001248 return ret;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001249}
1250
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001251#ifdef FIXED_POINT
1252
1253#ifndef DISABLE_FLOAT_API
Jean-Marc Valin24ed4652012-05-18 15:14:17 -04001254opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size,
Gregory Maxwelle7028172011-11-19 23:58:09 -05001255 unsigned char *data, opus_int32 max_data_bytes)
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001256{
1257 int i, ret;
1258 VARDECL(opus_int16, in);
1259 ALLOC_STACK;
1260
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001261 if(frame_size<0)
1262 {
1263 RESTORE_STACK;
1264 return OPUS_BAD_ARG;
1265 }
Gregory Maxwelle699c192011-11-25 23:53:15 -05001266
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001267 ALLOC(in, frame_size*st->channels, opus_int16);
1268
1269 for (i=0;i<frame_size*st->channels;i++)
1270 in[i] = FLOAT2INT16(pcm[i]);
1271 ret = opus_encode(st, in, frame_size, data, max_data_bytes);
1272 RESTORE_STACK;
1273 return ret;
1274}
1275#endif
1276
1277#else
Jean-Marc Valin59354a72012-03-08 12:19:07 -05001278opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size,
Gregory Maxwelle7028172011-11-19 23:58:09 -05001279 unsigned char *data, opus_int32 max_data_bytes)
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001280{
1281 int i, ret;
1282 VARDECL(float, in);
1283 ALLOC_STACK;
1284
1285 ALLOC(in, frame_size*st->channels, float);
1286
1287 for (i=0;i<frame_size*st->channels;i++)
Koen Vos854fe702011-10-09 20:34:41 -04001288 in[i] = (1.0f/32768)*pcm[i];
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001289 ret = opus_encode_float(st, in, frame_size, data, max_data_bytes);
1290 RESTORE_STACK;
1291 return ret;
1292}
1293#endif
1294
1295
Jean-Marc Valin955f94c2011-03-08 22:12:43 -05001296int opus_encoder_ctl(OpusEncoder *st, int request, ...)
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001297{
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001298 int ret;
Ralph Giles641eea82011-08-02 10:06:59 -07001299 CELTEncoder *celt_enc;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001300 va_list ap;
1301
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001302 ret = OPUS_OK;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001303 va_start(ap, request);
1304
Jean-Marc Valin5095c472011-05-05 19:47:48 -04001305 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
1306
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001307 switch (request)
1308 {
Jean-Marc Valin69549ac2011-08-18 17:28:28 -04001309 case OPUS_SET_APPLICATION_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001310 {
Ralph Giles04cca282011-08-24 00:29:29 -04001311 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -04001312 if ( (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO
1313 && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
1314 || (!st->first && st->application != value))
1315 {
1316 ret = OPUS_BAD_ARG;
1317 break;
1318 }
Jean-Marc Valin69549ac2011-08-18 17:28:28 -04001319 st->application = value;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001320 }
1321 break;
Jean-Marc Valin69549ac2011-08-18 17:28:28 -04001322 case OPUS_GET_APPLICATION_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001323 {
Ralph Giles04cca282011-08-24 00:29:29 -04001324 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001325 *value = st->application;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001326 }
1327 break;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001328 case OPUS_SET_BITRATE_REQUEST:
1329 {
Ralph Giles04cca282011-08-24 00:29:29 -04001330 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001331 if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
Jean-Marc Valinba547462011-05-10 17:54:41 -04001332 {
1333 if (value <= 0)
1334 goto bad_arg;
1335 else if (value <= 500)
1336 value = 500;
Jean-Marc Valin69f44c52011-09-07 02:43:23 -04001337 else if (value > (opus_int32)300000*st->channels)
1338 value = (opus_int32)300000*st->channels;
Jean-Marc Valinba547462011-05-10 17:54:41 -04001339 }
1340 st->user_bitrate_bps = value;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001341 }
1342 break;
1343 case OPUS_GET_BITRATE_REQUEST:
1344 {
Ralph Giles04cca282011-08-24 00:29:29 -04001345 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001346 *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001347 }
1348 break;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001349 case OPUS_SET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001350 {
Ralph Giles04cca282011-08-24 00:29:29 -04001351 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwellb9f443d2011-10-04 01:20:39 -04001352 if((value<1 || value>st->channels) && value != OPUS_AUTO)
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001353 return OPUS_BAD_ARG;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001354 st->force_channels = value;
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001355 }
1356 break;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001357 case OPUS_GET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001358 {
Ralph Giles04cca282011-08-24 00:29:29 -04001359 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001360 *value = st->force_channels;
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001361 }
1362 break;
Jean-Marc Valin9ba17432011-10-24 22:41:18 -04001363 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
1364 {
1365 opus_int32 value = va_arg(ap, opus_int32);
1366 if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)
1367 return OPUS_BAD_ARG;
1368 st->max_bandwidth = value;
1369 if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
1370 st->silk_mode.maxInternalSampleRate = 8000;
1371 } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
1372 st->silk_mode.maxInternalSampleRate = 12000;
1373 } else {
1374 st->silk_mode.maxInternalSampleRate = 16000;
1375 }
1376 }
1377 break;
1378 case OPUS_GET_MAX_BANDWIDTH_REQUEST:
1379 {
1380 opus_int32 *value = va_arg(ap, opus_int32*);
1381 *value = st->max_bandwidth;
1382 }
1383 break;
Jean-Marc Valin05dd36a2010-10-18 12:50:49 -04001384 case OPUS_SET_BANDWIDTH_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001385 {
Ralph Giles04cca282011-08-24 00:29:29 -04001386 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001387 if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO)
Ralph Giles04cca282011-08-24 00:29:29 -04001388 return OPUS_BAD_ARG;
Jean-Marc Valin955f94c2011-03-08 22:12:43 -05001389 st->user_bandwidth = value;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -04001390 if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001391 st->silk_mode.maxInternalSampleRate = 8000;
Gregory Maxwell87141892011-10-02 03:19:15 -04001392 } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001393 st->silk_mode.maxInternalSampleRate = 12000;
1394 } else {
1395 st->silk_mode.maxInternalSampleRate = 16000;
1396 }
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001397 }
1398 break;
Jean-Marc Valin05dd36a2010-10-18 12:50:49 -04001399 case OPUS_GET_BANDWIDTH_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001400 {
Ralph Giles04cca282011-08-24 00:29:29 -04001401 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001402 *value = st->bandwidth;
1403 }
1404 break;
Jean-Marc Valind4827732011-08-19 17:07:16 -04001405 case OPUS_SET_DTX_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001406 {
Ralph Giles04cca282011-08-24 00:29:29 -04001407 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001408 if(value<0 || value>1)
1409 return OPUS_BAD_ARG;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001410 st->silk_mode.useDTX = value;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001411 }
1412 break;
Jean-Marc Valind4827732011-08-19 17:07:16 -04001413 case OPUS_GET_DTX_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001414 {
Ralph Giles04cca282011-08-24 00:29:29 -04001415 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001416 *value = st->silk_mode.useDTX;
1417 }
1418 break;
1419 case OPUS_SET_COMPLEXITY_REQUEST:
1420 {
Ralph Giles04cca282011-08-24 00:29:29 -04001421 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001422 if(value<0 || value>10)
1423 return OPUS_BAD_ARG;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001424 st->silk_mode.complexity = value;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001425 celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001426 }
1427 break;
1428 case OPUS_GET_COMPLEXITY_REQUEST:
1429 {
Ralph Giles04cca282011-08-24 00:29:29 -04001430 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001431 *value = st->silk_mode.complexity;
1432 }
1433 break;
Jean-Marc Valine766d9f2011-08-28 20:27:18 -04001434 case OPUS_SET_INBAND_FEC_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001435 {
Ralph Giles04cca282011-08-24 00:29:29 -04001436 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001437 if(value<0 || value>1)
1438 return OPUS_BAD_ARG;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001439 st->silk_mode.useInBandFEC = value;
1440 }
1441 break;
Jean-Marc Valine766d9f2011-08-28 20:27:18 -04001442 case OPUS_GET_INBAND_FEC_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001443 {
Ralph Giles04cca282011-08-24 00:29:29 -04001444 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001445 *value = st->silk_mode.useInBandFEC;
1446 }
1447 break;
1448 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1449 {
Ralph Giles04cca282011-08-24 00:29:29 -04001450 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valind2124cd2011-04-25 13:36:14 -04001451 if (value < 0 || value > 100)
1452 return OPUS_BAD_ARG;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001453 st->silk_mode.packetLossPercentage = value;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001454 celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value));
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001455 }
1456 break;
1457 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1458 {
Ralph Giles04cca282011-08-24 00:29:29 -04001459 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001460 *value = st->silk_mode.packetLossPercentage;
1461 }
1462 break;
Jean-Marc Valind7f67002011-08-18 16:55:24 -04001463 case OPUS_SET_VBR_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001464 {
Ralph Giles04cca282011-08-24 00:29:29 -04001465 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001466 if(value<0 || value>1)
1467 return OPUS_BAD_ARG;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001468 st->use_vbr = value;
1469 st->silk_mode.useCBR = 1-value;
1470 }
1471 break;
Jean-Marc Valind7f67002011-08-18 16:55:24 -04001472 case OPUS_GET_VBR_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001473 {
Ralph Giles04cca282011-08-24 00:29:29 -04001474 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001475 *value = st->use_vbr;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001476 }
1477 break;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001478 case OPUS_SET_VOICE_RATIO_REQUEST:
1479 {
Ralph Giles04cca282011-08-24 00:29:29 -04001480 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001481 if (value>100 || value<-1)
Jean-Marc Valind2124cd2011-04-25 13:36:14 -04001482 goto bad_arg;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001483 st->voice_ratio = value;
1484 }
1485 break;
1486 case OPUS_GET_VOICE_RATIO_REQUEST:
1487 {
Ralph Giles04cca282011-08-24 00:29:29 -04001488 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001489 *value = st->voice_ratio;
1490 }
1491 break;
Jean-Marc Valinb55b6612011-03-14 15:11:44 -04001492 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
1493 {
Ralph Giles04cca282011-08-24 00:29:29 -04001494 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001495 if(value<0 || value>1)
1496 return OPUS_BAD_ARG;
Jean-Marc Valinb55b6612011-03-14 15:11:44 -04001497 st->vbr_constraint = value;
1498 }
1499 break;
1500 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1501 {
Ralph Giles04cca282011-08-24 00:29:29 -04001502 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valinb55b6612011-03-14 15:11:44 -04001503 *value = st->vbr_constraint;
1504 }
1505 break;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04001506 case OPUS_SET_SIGNAL_REQUEST:
1507 {
Ralph Giles04cca282011-08-24 00:29:29 -04001508 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001509 if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC)
1510 return OPUS_BAD_ARG;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04001511 st->signal_type = value;
1512 }
1513 break;
1514 case OPUS_GET_SIGNAL_REQUEST:
1515 {
Ralph Giles04cca282011-08-24 00:29:29 -04001516 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04001517 *value = st->signal_type;
1518 }
1519 break;
Jean-Marc Valin9d8b5192011-08-03 12:44:37 -04001520 case OPUS_GET_LOOKAHEAD_REQUEST:
1521 {
Ralph Giles04cca282011-08-24 00:29:29 -04001522 opus_int32 *value = va_arg(ap, opus_int32*);
Jean-Marc Valind186c912011-09-08 15:13:46 -04001523 *value = st->Fs/400;
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -04001524 if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
Koen Vos854fe702011-10-09 20:34:41 -04001525 *value += st->delay_compensation;
Jean-Marc Valin9d8b5192011-08-03 12:44:37 -04001526 }
1527 break;
Jean-Marc Valind4827732011-08-19 17:07:16 -04001528 case OPUS_GET_FINAL_RANGE_REQUEST:
1529 {
1530 opus_uint32 *value = va_arg(ap, opus_uint32*);
1531 *value = st->rangeFinal;
1532 }
1533 break;
Jean-Marc Valin927488b2011-08-30 20:09:22 -04001534 case OPUS_RESET_STATE:
1535 {
1536 void *silk_enc;
1537 silk_EncControlStruct dummy;
1538 silk_enc = (char*)st+st->silk_enc_offset;
1539
1540 OPUS_CLEAR((char*)&st->OPUS_ENCODER_RESET_START,
Gregory Maxwelld32f9482011-09-04 07:48:20 -04001541 sizeof(OpusEncoder)-
Jean-Marc Valin927488b2011-08-30 20:09:22 -04001542 ((char*)&st->OPUS_ENCODER_RESET_START - (char*)st));
1543
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001544 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
Jean-Marc Valin927488b2011-08-30 20:09:22 -04001545 silk_InitEncoder( silk_enc, &dummy );
1546 st->stream_channels = st->channels;
Koen Vos854fe702011-10-09 20:34:41 -04001547 st->hybrid_stereo_width_Q14 = 1 << 14;
Jean-Marc Valin927488b2011-08-30 20:09:22 -04001548 st->first = 1;
1549 st->mode = MODE_HYBRID;
1550 st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -07001551 st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
Jean-Marc Valin927488b2011-08-30 20:09:22 -04001552 }
1553 break;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001554 case OPUS_SET_FORCE_MODE_REQUEST:
1555 {
1556 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwelled921b02011-10-02 20:04:28 -04001557 if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO)
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001558 goto bad_arg;
1559 st->user_forced_mode = value;
1560 }
1561 break;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001562 default:
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001563 /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001564 ret = OPUS_UNIMPLEMENTED;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001565 break;
Jean-Marc Valinc5ea0742010-07-05 11:11:54 -04001566 }
Alfred E. Heggestad3d31d702010-07-27 16:38:04 +02001567 va_end(ap);
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001568 return ret;
Jean-Marc Valind2124cd2011-04-25 13:36:14 -04001569bad_arg:
1570 va_end(ap);
1571 return OPUS_BAD_ARG;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -04001572}
1573
Jean-Marc Valin05dd36a2010-10-18 12:50:49 -04001574void opus_encoder_destroy(OpusEncoder *st)
Jean-Marc Valin3e66e912010-06-30 14:16:14 -04001575{
Jean-Marc Valin07f88402011-08-29 15:08:51 -04001576 opus_free(st);
Jean-Marc Valin3e66e912010-06-30 14:16:14 -04001577}