blob: 4304db4a08dd08121936d1f01721a57f666e8a64 [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"
Aurélien Zanellicd4c8242013-05-31 15:07:00 +020043#include "cpu_support.h"
Jean-Marc Valinc5880fe2012-07-05 01:28:45 -040044#include "analysis.h"
45#include "mathops.h"
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070046#include "tuning_parameters.h"
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040047#ifdef FIXED_POINT
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070048#include "fixed/structs_FIX.h"
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040049#else
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070050#include "float/structs_FLP.h"
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040051#endif
52
Jean-Marc Valind9920f32011-08-19 13:00:49 -040053#define MAX_ENCODER_BUFFER 480
54
Jean-Marc Valind865fe62013-03-11 11:35:10 -040055typedef struct {
56 opus_val32 XX, XY, YY;
57 opus_val16 smoothed_width;
58 opus_val16 max_follower;
59} StereoWidthState;
60
Jean-Marc Valind9920f32011-08-19 13:00:49 -040061struct OpusEncoder {
62 int celt_enc_offset;
63 int silk_enc_offset;
64 silk_EncControlStruct silk_mode;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040065 int application;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040066 int channels;
67 int delay_compensation;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -040068 int force_channels;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040069 int signal_type;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040070 int user_bandwidth;
Jean-Marc Valin9ba17432011-10-24 22:41:18 -040071 int max_bandwidth;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -040072 int user_forced_mode;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040073 int voice_ratio;
Gregory Maxwell64a35412011-09-02 10:31:17 -040074 opus_int32 Fs;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040075 int use_vbr;
76 int vbr_constraint;
Jean-Marc Valin49583ed2012-11-22 13:11:43 -050077 int variable_duration;
Jean-Marc Valin8fdf2af2011-09-10 21:56:34 -040078 opus_int32 bitrate_bps;
79 opus_int32 user_bitrate_bps;
Jean-Marc Valin7509fdb2012-12-20 22:48:35 -050080 int lsb_depth;
Jean-Marc Valind9920f32011-08-19 13:00:49 -040081 int encoder_buffer;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -040082 int lfe;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040083
84#define OPUS_ENCODER_RESET_START stream_channels
85 int stream_channels;
Jean-Marc Valin8fdf2af2011-09-10 21:56:34 -040086 opus_int16 hybrid_stereo_width_Q14;
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040087 opus_int32 variable_HP_smth2_Q15;
Jean-Marc Valinf68799b2012-07-12 17:36:11 -040088 opus_val16 prev_HB_gain;
Jean-Marc Valin957f7f12011-09-01 18:02:43 -040089 opus_val32 hp_mem[4];
Jean-Marc Valin927488b2011-08-30 20:09:22 -040090 int mode;
91 int prev_mode;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -040092 int prev_channels;
Gregory Maxwell220a7d42011-10-01 20:30:16 -040093 int prev_framesize;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040094 int bandwidth;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -040095 int silk_bw_switch;
Jean-Marc Valin927488b2011-08-30 20:09:22 -040096 /* Sampling rate (at the API level) */
Jean-Marc Valind9920f32011-08-19 13:00:49 -040097 int first;
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -040098 opus_val16 * energy_masking;
Jean-Marc Valind865fe62013-03-11 11:35:10 -040099 StereoWidthState width_mem;
Jean-Marc Valind9920f32011-08-19 13:00:49 -0400100 opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2];
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400101#ifndef DISABLE_FLOAT_API
Jean-Marc Valine9c353a2011-11-14 17:58:29 +0800102 TonalityAnalysisState analysis;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500103 int detected_bandwidth;
104 int analysis_offset;
Jean-Marc Valine9c353a2011-11-14 17:58:29 +0800105#endif
Gregory Maxwell64a35412011-09-02 10:31:17 -0400106 opus_uint32 rangeFinal;
Aurélien Zanellicd4c8242013-05-31 15:07:00 +0200107 int arch;
Jean-Marc Valind9920f32011-08-19 13:00:49 -0400108};
109
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400110/* Transition tables for the voice and music. First column is the
Jean-Marc Valin9edde422011-05-05 15:30:44 -0400111 middle (memoriless) threshold. The second column is the hysteresis
112 (difference with the middle) */
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400113static const opus_int32 mono_voice_bandwidth_thresholds[8] = {
Ralph Giles04cca282011-08-24 00:29:29 -0400114 11000, 1000, /* NB<->MB */
115 14000, 1000, /* MB<->WB */
Koen Vos0b00b312012-07-12 14:55:49 -0400116 17000, 1000, /* WB<->SWB */
117 20000, 1000, /* SWB<->FB */
Jean-Marc Valin09c67662011-05-04 22:34:53 -0400118};
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400119static const opus_int32 mono_music_bandwidth_thresholds[8] = {
120 14000, 1000, /* MB not allowed */
121 18000, 2000, /* MB<->WB */
122 24000, 2000, /* WB<->SWB */
Ralph Giles04cca282011-08-24 00:29:29 -0400123 33000, 2000, /* SWB<->FB */
Jean-Marc Valin09c67662011-05-04 22:34:53 -0400124};
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400125static const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
126 11000, 1000, /* NB<->MB */
127 14000, 1000, /* MB<->WB */
128 21000, 2000, /* WB<->SWB */
129 32000, 2000, /* SWB<->FB */
130};
131static const opus_int32 stereo_music_bandwidth_thresholds[8] = {
132 14000, 1000, /* MB not allowed */
133 18000, 2000, /* MB<->WB */
134 24000, 2000, /* WB<->SWB */
135 48000, 2000, /* SWB<->FB */
136};
137/* Threshold bit-rates for switching between mono and stereo */
Jean-Marc Valinfa43c772013-03-08 11:35:15 -0500138static const opus_int32 stereo_voice_threshold = 31000;
139static const opus_int32 stereo_music_threshold = 31000;
Jean-Marc Valin09c67662011-05-04 22:34:53 -0400140
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400141/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */
142static const opus_int32 mode_thresholds[2][2] = {
143 /* voice */ /* music */
Jean-Marc Valind865fe62013-03-11 11:35:10 -0400144 { 64000, 20000}, /* mono */
145 { 36000, 20000}, /* stereo */
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400146};
Jean-Marc Valinb5972382011-10-07 08:38:27 -0400147
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400148int opus_encoder_get_size(int channels)
149{
Ralph Giles641eea82011-08-02 10:06:59 -0700150 int silkEncSizeBytes, celtEncSizeBytes;
151 int ret;
Gregory Maxwellf451b332011-09-04 10:47:15 -0400152 if (channels<1 || channels > 2)
153 return 0;
Ralph Giles641eea82011-08-02 10:06:59 -0700154 ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
Ralph Giles04cca282011-08-24 00:29:29 -0400155 if (ret)
Ralph Giles641eea82011-08-02 10:06:59 -0700156 return 0;
157 silkEncSizeBytes = align(silkEncSizeBytes);
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400158 celtEncSizeBytes = celt_encoder_get_size(channels);
159 return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400160}
161
Gregory Maxwell64a35412011-09-02 10:31:17 -0400162int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application)
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400163{
Ralph Giles641eea82011-08-02 10:06:59 -0700164 void *silk_enc;
165 CELTEncoder *celt_enc;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500166 int err;
Ralph Giles641eea82011-08-02 10:06:59 -0700167 int ret, silkEncSizeBytes;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400168
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400169 if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
170 (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
171 && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400172 return OPUS_BAD_ARG;
Jean-Marc Valind3358b12011-06-14 14:48:53 -0400173
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400174 OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
Jean-Marc Valind3358b12011-06-14 14:48:53 -0400175 /* Create SILK encoder */
176 ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
Ralph Giles04cca282011-08-24 00:29:29 -0400177 if (ret)
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400178 return OPUS_BAD_ARG;
Ralph Giles04cca282011-08-24 00:29:29 -0400179 silkEncSizeBytes = align(silkEncSizeBytes);
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400180 st->silk_enc_offset = align(sizeof(OpusEncoder));
181 st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
Jean-Marc Valin5095c472011-05-05 19:47:48 -0400182 silk_enc = (char*)st+st->silk_enc_offset;
183 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
184
Jean-Marc Valinb3864582011-01-31 12:41:49 -0500185 st->stream_channels = st->channels = channels;
Jean-Marc Valinbcdfe632010-08-31 11:22:43 -0400186
187 st->Fs = Fs;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400188
Aurélien Zanellicd4c8242013-05-31 15:07:00 +0200189 st->arch = opus_select_arch();
190
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400191 ret = silk_InitEncoder( silk_enc, &st->silk_mode );
Gregory Maxwelle03af442011-09-04 04:43:11 -0400192 if(ret)return OPUS_INTERNAL_ERROR;
Jean-Marc Valinae180902010-07-19 11:44:36 -0400193
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500194 /* default SILK parameters */
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400195 st->silk_mode.nChannelsAPI = channels;
196 st->silk_mode.nChannelsInternal = channels;
197 st->silk_mode.API_sampleRate = st->Fs;
198 st->silk_mode.maxInternalSampleRate = 16000;
199 st->silk_mode.minInternalSampleRate = 8000;
200 st->silk_mode.desiredInternalSampleRate = 16000;
201 st->silk_mode.payloadSize_ms = 20;
202 st->silk_mode.bitRate = 25000;
203 st->silk_mode.packetLossPercentage = 0;
Jean-Marc Valinf5645f52013-09-16 14:36:53 -0400204 st->silk_mode.complexity = 9;
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400205 st->silk_mode.useInBandFEC = 0;
206 st->silk_mode.useDTX = 0;
207 st->silk_mode.useCBR = 0;
208
Jean-Marc Valinc5ea0742010-07-05 11:11:54 -0400209 /* Create CELT encoder */
Ralph Giles641eea82011-08-02 10:06:59 -0700210 /* Initialize CELT encoder */
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400211 err = celt_encoder_init(celt_enc, Fs, channels);
Gregory Maxwelle03af442011-09-04 04:43:11 -0400212 if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR;
213
Jean-Marc Valin5095c472011-05-05 19:47:48 -0400214 celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0));
Jean-Marc Valinf5645f52013-09-16 14:36:53 -0400215 celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(st->silk_mode.complexity));
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400216
Jean-Marc Valin21452882011-09-09 14:57:43 -0400217 st->use_vbr = 1;
Jean-Marc Valin66820f32012-01-31 02:03:39 -0500218 /* Makes constrained VBR the default (safer for real-time use) */
219 st->vbr_constraint = 1;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400220 st->user_bitrate_bps = OPUS_AUTO;
Ralph Giles641eea82011-08-02 10:06:59 -0700221 st->bitrate_bps = 3000+Fs*channels;
Jean-Marc Valin69549ac2011-08-18 17:28:28 -0400222 st->application = application;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400223 st->signal_type = OPUS_AUTO;
224 st->user_bandwidth = OPUS_AUTO;
Jean-Marc Valin9ba17432011-10-24 22:41:18 -0400225 st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -0400226 st->force_channels = OPUS_AUTO;
227 st->user_forced_mode = OPUS_AUTO;
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400228 st->voice_ratio = -1;
Ralph Giles641eea82011-08-02 10:06:59 -0700229 st->encoder_buffer = st->Fs/100;
Jean-Marc Valin7509fdb2012-12-20 22:48:35 -0500230 st->lsb_depth = 24;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500231 st->variable_duration = OPUS_FRAMESIZE_ARG;
Jean-Marc Valin927488b2011-08-30 20:09:22 -0400232
Koen Vosbf75c8e2011-12-13 14:47:31 -0500233 /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead
234 + 1.5 ms for SILK resamplers and stereo prediction) */
235 st->delay_compensation = st->Fs/250;
Jean-Marc Valinb5972382011-10-07 08:38:27 -0400236
Koen Vosbf75c8e2011-12-13 14:47:31 -0500237 st->hybrid_stereo_width_Q14 = 1 << 14;
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400238 st->prev_HB_gain = Q15ONE;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700239 st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
Jean-Marc Valin927488b2011-08-30 20:09:22 -0400240 st->first = 1;
241 st->mode = MODE_HYBRID;
242 st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
243
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400244 return OPUS_OK;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400245}
246
Jean-Marc Valin78291b22011-10-08 22:12:31 -0400247static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)
Jean-Marc Valin421a6282011-08-18 14:32:16 -0400248{
249 int period;
250 unsigned char toc;
251 period = 0;
252 while (framerate < 400)
253 {
254 framerate <<= 1;
255 period++;
256 }
257 if (mode == MODE_SILK_ONLY)
258 {
Jean-Marc Valin78291b22011-10-08 22:12:31 -0400259 toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5;
Jean-Marc Valin421a6282011-08-18 14:32:16 -0400260 toc |= (period-2)<<3;
261 } else if (mode == MODE_CELT_ONLY)
262 {
263 int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND;
264 if (tmp < 0)
265 tmp = 0;
266 toc = 0x80;
267 toc |= tmp << 5;
268 toc |= period<<3;
269 } else /* Hybrid */
270 {
271 toc = 0x60;
272 toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4;
273 toc |= (period-2)<<3;
274 }
275 toc |= (channels==2)<<2;
276 return toc;
277}
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400278
279#ifndef FIXED_POINT
Diego Elio PettenĂ²d006b782012-09-10 01:48:22 -0700280static void silk_biquad_float(
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400281 const opus_val16 *in, /* I: Input signal */
282 const opus_int32 *B_Q28, /* I: MA coefficients [3] */
283 const opus_int32 *A_Q28, /* I: AR coefficients [2] */
284 opus_val32 *S, /* I/O: State vector [2] */
285 opus_val16 *out, /* O: Output signal */
286 const opus_int32 len, /* I: Signal length (must be even) */
287 int stride
288)
289{
290 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
291 opus_int k;
292 opus_val32 vout;
293 opus_val32 inval;
294 opus_val32 A[2], B[3];
295
Gregory Maxwell37f56592012-07-17 17:40:55 -0400296 A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28)));
297 A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28)));
298 B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28)));
299 B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28)));
300 B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28)));
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400301
302 /* Negate A_Q28 values and split in two parts */
303
304 for( k = 0; k < len; k++ ) {
305 /* S[ 0 ], S[ 1 ]: Q12 */
306 inval = in[ k*stride ];
307 vout = S[ 0 ] + B[0]*inval;
308
309 S[ 0 ] = S[1] - vout*A[0] + B[1]*inval;
310
Jean-Marc Valin03e82032013-08-12 14:47:14 -0400311 S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL;
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400312
313 /* Scale back to Q0 and saturate */
314 out[ k*stride ] = vout;
315 }
316}
317#endif
318
319static 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)
320{
321 opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];
322 opus_int32 Fc_Q19, r_Q28, r_Q22;
323
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700324 silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) );
325 Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 );
326 silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400327
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700328 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 -0400329
330 /* b = r * [ 1; -2; 1 ]; */
331 /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */
332 B_Q28[ 0 ] = r_Q28;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700333 B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400334 B_Q28[ 2 ] = r_Q28;
335
336 /* -r * ( 2 - Fc * Fc ); */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700337 r_Q22 = silk_RSHIFT( r_Q28, 6 );
338 A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) );
339 A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400340
341#ifdef FIXED_POINT
342 silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels );
343 if( channels == 2 ) {
344 silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
345 }
346#else
347 silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );
348 if( channels == 2 ) {
349 silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
350 }
351#endif
352}
353
Jean-Marc Valinac2e6232011-12-29 01:23:33 -0500354#ifdef FIXED_POINT
355static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
356{
357 int c, i;
358 int shift;
359
360 /* Approximates -round(log2(4.*cutoff_Hz/Fs)) */
361 shift=celt_ilog2(Fs/(cutoff_Hz*3));
362 for (c=0;c<channels;c++)
363 {
364 for (i=0;i<len;i++)
365 {
366 opus_val32 x, tmp, y;
367 x = SHL32(EXTEND32(in[channels*i+c]), 15);
368 /* First stage */
369 tmp = x-hp_mem[2*c];
370 hp_mem[2*c] = hp_mem[2*c] + PSHR32(x - hp_mem[2*c], shift);
371 /* Second stage */
372 y = tmp - hp_mem[2*c+1];
373 hp_mem[2*c+1] = hp_mem[2*c+1] + PSHR32(tmp - hp_mem[2*c+1], shift);
374 out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 15), 32767));
375 }
376 }
377}
378
379#else
Jean-Marc Valindb13c382011-12-23 11:58:43 -0500380static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
381{
382 int c, i;
383 float coef;
384
Ralph Giles027ec512012-10-23 10:49:18 -0700385 coef = 4.0f*cutoff_Hz/Fs;
Jean-Marc Valindb13c382011-12-23 11:58:43 -0500386 for (c=0;c<channels;c++)
387 {
388 for (i=0;i<len;i++)
389 {
390 opus_val32 x, tmp, y;
391 x = in[channels*i+c];
392 /* First stage */
393 tmp = x-hp_mem[2*c];
Jean-Marc Valin260474f2013-07-12 01:22:09 -0400394 hp_mem[2*c] = hp_mem[2*c] + coef*(x - hp_mem[2*c]) + VERY_SMALL;
Jean-Marc Valindb13c382011-12-23 11:58:43 -0500395 /* Second stage */
396 y = tmp - hp_mem[2*c+1];
Jean-Marc Valin260474f2013-07-12 01:22:09 -0400397 hp_mem[2*c+1] = hp_mem[2*c+1] + coef*(tmp - hp_mem[2*c+1]) + VERY_SMALL;
Jean-Marc Valindb13c382011-12-23 11:58:43 -0500398 out[channels*i+c] = y;
399 }
400 }
401}
Jean-Marc Valinac2e6232011-12-29 01:23:33 -0500402#endif
Jean-Marc Valindb13c382011-12-23 11:58:43 -0500403
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -0400404static void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
Jean-Marc Valin37d9e132012-07-11 15:53:39 -0400405 int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -0400406{
407 int i;
Jean-Marc Valin37d9e132012-07-11 15:53:39 -0400408 int overlap;
409 int inc;
410 inc = 48000/Fs;
411 overlap=overlap48/inc;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -0400412 g1 = Q15ONE-g1;
413 g2 = Q15ONE-g2;
414 for (i=0;i<overlap;i++)
415 {
416 opus_val32 diff;
417 opus_val16 g, w;
418 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
419 g = SHR32(MAC16_16(MULT16_16(w,g2),
420 Q15ONE-w, g1), 15);
421 diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
422 diff = MULT16_16_Q15(g, diff);
423 out[i*channels] = out[i*channels] - diff;
424 out[i*channels+1] = out[i*channels+1] + diff;
425 }
426 for (;i<frame_size;i++)
427 {
428 opus_val32 diff;
429 diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
430 diff = MULT16_16_Q15(g2, diff);
431 out[i*channels] = out[i*channels] - diff;
432 out[i*channels+1] = out[i*channels+1] + diff;
433 }
434}
435
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400436static void gain_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
437 int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
438{
439 int i;
440 int inc;
441 int overlap;
Jean-Marc Valinca242592012-10-16 00:26:32 -0400442 int c;
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400443 inc = 48000/Fs;
444 overlap=overlap48/inc;
Jean-Marc Valinca242592012-10-16 00:26:32 -0400445 if (channels==1)
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400446 {
Jean-Marc Valinca242592012-10-16 00:26:32 -0400447 for (i=0;i<overlap;i++)
448 {
449 opus_val16 g, w;
450 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
451 g = SHR32(MAC16_16(MULT16_16(w,g2),
452 Q15ONE-w, g1), 15);
453 out[i] = MULT16_16_Q15(g, in[i]);
454 }
455 } else {
456 for (i=0;i<overlap;i++)
457 {
458 opus_val16 g, w;
459 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
460 g = SHR32(MAC16_16(MULT16_16(w,g2),
461 Q15ONE-w, g1), 15);
462 out[i*2] = MULT16_16_Q15(g, in[i*2]);
463 out[i*2+1] = MULT16_16_Q15(g, in[i*2+1]);
464 }
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400465 }
Jean-Marc Valinca242592012-10-16 00:26:32 -0400466 c=0;do {
Jean-Marc Valin4ed7e482013-02-05 01:32:52 -0500467 for (i=overlap;i<frame_size;i++)
Jean-Marc Valinca242592012-10-16 00:26:32 -0400468 {
469 out[i*channels+c] = MULT16_16_Q15(g2, in[i*channels+c]);
470 }
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400471 }
Jean-Marc Valinca242592012-10-16 00:26:32 -0400472 while (++c<channels);
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400473}
474
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400475OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400476{
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400477 int ret;
Gregory Maxwelle98f1f52011-10-05 01:59:28 -0400478 OpusEncoder *st;
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400479 if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
480 (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
481 && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
482 {
483 if (error)
484 *error = OPUS_BAD_ARG;
485 return NULL;
486 }
Gregory Maxwelle98f1f52011-10-05 01:59:28 -0400487 st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
Jean-Marc Valin85b8e622011-08-29 16:10:08 -0400488 if (st == NULL)
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400489 {
490 if (error)
491 *error = OPUS_ALLOC_FAIL;
492 return NULL;
493 }
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400494 ret = opus_encoder_init(st, Fs, channels, application);
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400495 if (error)
496 *error = ret;
497 if (ret != OPUS_OK)
498 {
Jean-Marc Valin85b8e622011-08-29 16:10:08 -0400499 opus_free(st);
500 st = NULL;
Jean-Marc Valin9d8dc3a2011-08-29 09:40:57 -0400501 }
Jean-Marc Valin85b8e622011-08-29 16:10:08 -0400502 return st;
Jean-Marc Valin280c0602011-05-05 20:47:42 -0400503}
Gregory Maxwell220a7d42011-10-01 20:30:16 -0400504
505static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int max_data_bytes)
506{
507 if(!frame_size)frame_size=st->Fs/400;
508 if (st->user_bitrate_bps==OPUS_AUTO)
509 return 60*st->Fs/frame_size + st->Fs*st->channels;
510 else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
511 return max_data_bytes*8*st->Fs/frame_size;
512 else
513 return st->user_bitrate_bps;
514}
515
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400516#ifndef DISABLE_FLOAT_API
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500517/* Don't use more than 60 ms for the frame size analysis */
518#define MAX_DYNAMIC_FRAMESIZE 24
519/* Estimates how much the bitrate will be boosted based on the sub-frame energy */
520static float transient_boost(const float *E, const float *E_1, int LM, int maxM)
521{
522 int i;
523 int M;
524 float sumE=0, sumE_1=0;
525 float metric;
526
527 M = IMIN(maxM, (1<<LM)+1);
528 for (i=0;i<M;i++)
529 {
530 sumE += E[i];
531 sumE_1 += E_1[i];
532 }
533 metric = sumE*sumE_1/(M*M);
534 /*if (LM==3)
535 printf("%f\n", metric);*/
536 /*return metric>10 ? 1 : 0;*/
537 /*return MAX16(0,1-exp(-.25*(metric-2.)));*/
Jean-Marc Valine83a3652013-06-27 14:45:50 -0400538 return MIN16(1,(float)sqrt(MAX16(0,.05f*(metric-2))));
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500539}
540
541/* Viterbi decoding trying to find the best frame size combination using look-ahead
542
543 State numbering:
544 0: unused
545 1: 2.5 ms
546 2: 5 ms (#1)
547 3: 5 ms (#2)
548 4: 10 ms (#1)
549 5: 10 ms (#2)
550 6: 10 ms (#3)
551 7: 10 ms (#4)
552 8: 20 ms (#1)
553 9: 20 ms (#2)
554 10: 20 ms (#3)
555 11: 20 ms (#4)
556 12: 20 ms (#5)
557 13: 20 ms (#6)
558 14: 20 ms (#7)
559 15: 20 ms (#8)
560*/
561static int transient_viterbi(const float *E, const float *E_1, int N, int frame_cost, int rate)
562{
563 int i;
564 float cost[MAX_DYNAMIC_FRAMESIZE][16];
565 int states[MAX_DYNAMIC_FRAMESIZE][16];
566 float best_cost;
567 int best_state;
Jean-Marc Valin3252bf22013-04-19 03:14:28 -0400568 float factor;
569 /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */
570 if (rate<80)
571 factor=0;
572 else if (rate>160)
573 factor=1;
574 else
575 factor = (rate-80.f)/80.f;
Jean-Marc Valinf548a5a2012-11-26 23:20:01 -0500576 /* Makes variable framesize less aggressive at lower bitrates, but I can't
Jean-Marc Valin3252bf22013-04-19 03:14:28 -0400577 find any valid theoretical justification for this (other than it seems
Jean-Marc Valinf548a5a2012-11-26 23:20:01 -0500578 to help) */
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500579 for (i=0;i<16;i++)
580 {
581 /* Impossible state */
582 states[0][i] = -1;
583 cost[0][i] = 1e10;
584 }
585 for (i=0;i<4;i++)
586 {
Jean-Marc Valin3252bf22013-04-19 03:14:28 -0400587 cost[0][1<<i] = (frame_cost + rate*(1<<i))*(1+factor*transient_boost(E, E_1, i, N+1));
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500588 states[0][1<<i] = i;
589 }
590 for (i=1;i<N;i++)
591 {
592 int j;
593
594 /* Follow continuations */
595 for (j=2;j<16;j++)
596 {
597 cost[i][j] = cost[i-1][j-1];
598 states[i][j] = j-1;
599 }
600
601 /* New frames */
602 for(j=0;j<4;j++)
603 {
604 int k;
605 float min_cost;
606 float curr_cost;
607 states[i][1<<j] = 1;
608 min_cost = cost[i-1][1];
609 for(k=1;k<4;k++)
610 {
611 float tmp = cost[i-1][(1<<(k+1))-1];
612 if (tmp < min_cost)
613 {
614 states[i][1<<j] = (1<<(k+1))-1;
615 min_cost = tmp;
616 }
617 }
Jean-Marc Valin3252bf22013-04-19 03:14:28 -0400618 curr_cost = (frame_cost + rate*(1<<j))*(1+factor*transient_boost(E+i, E_1+i, j, N-i+1));
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500619 cost[i][1<<j] = min_cost;
620 /* If part of the frame is outside the analysis window, only count part of the cost */
621 if (N-i < (1<<j))
622 cost[i][1<<j] += curr_cost*(float)(N-i)/(1<<j);
623 else
624 cost[i][1<<j] += curr_cost;
625 }
626 }
627
628 best_state=1;
629 best_cost = cost[N-1][1];
630 /* Find best end state (doesn't force a frame to end at N-1) */
631 for (i=2;i<16;i++)
632 {
633 if (cost[N-1][i]<best_cost)
634 {
635 best_cost = cost[N-1][i];
636 best_state = i;
637 }
638 }
639
640 /* Follow transitions back */
641 for (i=N-1;i>=0;i--)
642 {
643 /*printf("%d ", best_state);*/
644 best_state = states[i][best_state];
645 }
646 /*printf("%d\n", best_state);*/
647 return best_state;
648}
649
Jean-Marc Valin74483662012-12-17 16:23:42 -0500650int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
Jean-Marc Valin88481712013-11-13 11:57:31 -0500651 int bitrate, opus_val16 tonality, float *mem, int buffering,
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500652 downmix_func downmix)
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500653{
654 int N;
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500655 int i;
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500656 float e[MAX_DYNAMIC_FRAMESIZE+4];
657 float e_1[MAX_DYNAMIC_FRAMESIZE+3];
Jean-Marc Valin88481712013-11-13 11:57:31 -0500658 opus_val32 memx;
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500659 int bestLM=0;
660 int subframe;
661 int pos;
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400662 VARDECL(opus_val32, sub);
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500663
664 subframe = Fs/400;
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400665 ALLOC(sub, subframe, opus_val32);
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500666 e[0]=mem[0];
Jean-Marc Valin16ba19a2013-06-27 03:40:44 -0400667 e_1[0]=1.f/(EPSILON+mem[0]);
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500668 if (buffering)
669 {
670 /* Consider the CELT delay when not in restricted-lowdelay */
671 /* We assume the buffering is between 2.5 and 5 ms */
672 int offset = 2*subframe - buffering;
673 celt_assert(offset>=0 && offset <= subframe);
674 x += C*offset;
675 len -= offset;
676 e[1]=mem[1];
Jean-Marc Valin16ba19a2013-06-27 03:40:44 -0400677 e_1[1]=1.f/(EPSILON+mem[1]);
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500678 e[2]=mem[2];
Jean-Marc Valin16ba19a2013-06-27 03:40:44 -0400679 e_1[2]=1.f/(EPSILON+mem[2]);
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500680 pos = 3;
681 } else {
682 pos=1;
683 }
684 N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE);
Jean-Marc Valin88481712013-11-13 11:57:31 -0500685 /* Just silencing a warning, it's really initialized later */
686 memx = 0;
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500687 for (i=0;i<N;i++)
688 {
689 float tmp;
Jean-Marc Valin88481712013-11-13 11:57:31 -0500690 opus_val32 tmpx;
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500691 int j;
692 tmp=EPSILON;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500693
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400694 downmix(x, sub, subframe, i*subframe, 0, -2, C);
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500695 if (i==0)
696 memx = sub[0];
Jean-Marc Valin74483662012-12-17 16:23:42 -0500697 for (j=0;j<subframe;j++)
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500698 {
Jean-Marc Valin74483662012-12-17 16:23:42 -0500699 tmpx = sub[j];
Jean-Marc Valin88481712013-11-13 11:57:31 -0500700 tmp += (tmpx-memx)*(float)(tmpx-memx);
Jean-Marc Valin74483662012-12-17 16:23:42 -0500701 memx = tmpx;
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500702 }
703 e[i+pos] = tmp;
704 e_1[i+pos] = 1.f/tmp;
705 }
706 /* Hack to get 20 ms working with APPLICATION_AUDIO
707 The real problem is that the corresponding memory needs to use 1.5 ms
708 from this frame and 1 ms from the next frame */
709 e[i+pos] = e[i+pos-1];
710 if (buffering)
711 N=IMIN(MAX_DYNAMIC_FRAMESIZE, N+2);
Jean-Marc Valine83a3652013-06-27 14:45:50 -0400712 bestLM = transient_viterbi(e, e_1, N, (int)((1.f+.5f*tonality)*(60*C+40)), bitrate/400);
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500713 mem[0] = e[1<<bestLM];
714 if (buffering)
715 {
716 mem[1] = e[(1<<bestLM)+1];
717 mem[2] = e[(1<<bestLM)+2];
718 }
719 return bestLM;
720}
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500721
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500722#endif
723
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400724#ifndef DISABLE_FLOAT_API
Jean-Marc Valin1ad6f6d2013-10-01 19:25:40 -0400725#ifdef FIXED_POINT
726#define PCM2VAL(x) FLOAT2INT16(x)
727#else
728#define PCM2VAL(x) SCALEIN(x)
729#endif
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400730void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400731{
732 const float *x;
Jean-Marc Valinba7dbb32013-09-09 16:39:19 -0400733 opus_val32 scale;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400734 int j;
735 x = (const float *)_x;
736 for (j=0;j<subframe;j++)
Jean-Marc Valin1ad6f6d2013-10-01 19:25:40 -0400737 sub[j] = PCM2VAL(x[(j+offset)*C+c1]);
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400738 if (c2>-1)
739 {
740 for (j=0;j<subframe;j++)
Jean-Marc Valin1ad6f6d2013-10-01 19:25:40 -0400741 sub[j] += PCM2VAL(x[(j+offset)*C+c2]);
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400742 } else if (c2==-2)
743 {
744 int c;
745 for (c=1;c<C;c++)
746 {
747 for (j=0;j<subframe;j++)
Jean-Marc Valin1ad6f6d2013-10-01 19:25:40 -0400748 sub[j] += PCM2VAL(x[(j+offset)*C+c]);
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400749 }
750 }
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400751#ifdef FIXED_POINT
Jean-Marc Valinba7dbb32013-09-09 16:39:19 -0400752 scale = (1<<SIG_SHIFT);
753#else
754 scale = 1.f;
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400755#endif
Jean-Marc Valinba7dbb32013-09-09 16:39:19 -0400756 if (C==-2)
757 scale /= C;
758 else
759 scale /= 2;
760 for (j=0;j<subframe;j++)
761 sub[j] *= scale;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400762}
763#endif
764
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400765void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400766{
767 const opus_int16 *x;
Jean-Marc Valinba7dbb32013-09-09 16:39:19 -0400768 opus_val32 scale;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400769 int j;
770 x = (const opus_int16 *)_x;
771 for (j=0;j<subframe;j++)
772 sub[j] = x[(j+offset)*C+c1];
773 if (c2>-1)
774 {
775 for (j=0;j<subframe;j++)
776 sub[j] += x[(j+offset)*C+c2];
777 } else if (c2==-2)
778 {
779 int c;
780 for (c=1;c<C;c++)
781 {
782 for (j=0;j<subframe;j++)
783 sub[j] += x[(j+offset)*C+c];
784 }
785 }
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400786#ifdef FIXED_POINT
Jean-Marc Valinba7dbb32013-09-09 16:39:19 -0400787 scale = (1<<SIG_SHIFT);
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400788#else
Jean-Marc Valinba7dbb32013-09-09 16:39:19 -0400789 scale = 1.f/32768;
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400790#endif
Jean-Marc Valinba7dbb32013-09-09 16:39:19 -0400791 if (C==-2)
792 scale /= C;
793 else
794 scale /= 2;
795 for (j=0;j<subframe;j++)
796 sub[j] *= scale;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400797}
798
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500799opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs)
800{
801 int new_size;
802 if (frame_size<Fs/400)
803 return -1;
804 if (variable_duration == OPUS_FRAMESIZE_ARG)
805 new_size = frame_size;
806 else if (variable_duration == OPUS_FRAMESIZE_VARIABLE)
807 new_size = Fs/50;
808 else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_60_MS)
Jean-Marc Valin74f36b52013-02-20 22:31:49 -0500809 new_size = IMIN(3*Fs/50, (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500810 else
811 return -1;
812 if (new_size>frame_size)
813 return -1;
814 if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs &&
815 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs)
816 return -1;
817 return new_size;
818}
819
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400820opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
821 int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
Jean-Marc Valinc2b34412013-10-28 21:48:50 -0400822 int delay_compensation, downmix_func downmix
823#ifndef DISABLE_FLOAT_API
Jean-Marc Valin88481712013-11-13 11:57:31 -0500824 , float *subframe_mem
Jean-Marc Valinc2b34412013-10-28 21:48:50 -0400825#endif
826 )
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400827{
Jean-Marc Valinf5645f52013-09-16 14:36:53 -0400828#ifndef DISABLE_FLOAT_API
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400829 if (variable_duration == OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs/200)
830 {
831 int LM = 3;
832 LM = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps,
833 0, subframe_mem, delay_compensation, downmix);
834 while ((Fs/400<<LM)>frame_size)
835 LM--;
836 frame_size = (Fs/400<<LM);
Jean-Marc Valinf5645f52013-09-16 14:36:53 -0400837 } else
838#endif
839 {
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400840 frame_size = frame_size_select(frame_size, variable_duration, Fs);
841 }
842 if (frame_size<0)
843 return -1;
844 return frame_size;
845}
846
Jean-Marc Valind865fe62013-03-11 11:35:10 -0400847opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
848{
849 opus_val16 corr;
850 opus_val16 ldiff;
851 opus_val16 width;
852 opus_val32 xx, xy, yy;
853 opus_val16 sqrt_xx, sqrt_yy;
854 opus_val16 qrrt_xx, qrrt_yy;
855 int frame_rate;
856 int i;
857 opus_val16 short_alpha;
858
859 frame_rate = Fs/frame_size;
860 short_alpha = Q15ONE - 25*Q15ONE/IMAX(50,frame_rate);
861 xx=xy=yy=0;
862 for (i=0;i<frame_size;i+=4)
863 {
864 opus_val32 pxx=0;
865 opus_val32 pxy=0;
866 opus_val32 pyy=0;
867 opus_val16 x, y;
868 x = pcm[2*i];
869 y = pcm[2*i+1];
870 pxx = SHR32(MULT16_16(x,x),2);
871 pxy = SHR32(MULT16_16(x,y),2);
872 pyy = SHR32(MULT16_16(y,y),2);
873 x = pcm[2*i+2];
874 y = pcm[2*i+3];
875 pxx += SHR32(MULT16_16(x,x),2);
876 pxy += SHR32(MULT16_16(x,y),2);
877 pyy += SHR32(MULT16_16(y,y),2);
878 x = pcm[2*i+4];
879 y = pcm[2*i+5];
880 pxx += SHR32(MULT16_16(x,x),2);
881 pxy += SHR32(MULT16_16(x,y),2);
882 pyy += SHR32(MULT16_16(y,y),2);
883 x = pcm[2*i+6];
884 y = pcm[2*i+7];
885 pxx += SHR32(MULT16_16(x,x),2);
886 pxy += SHR32(MULT16_16(x,y),2);
887 pyy += SHR32(MULT16_16(y,y),2);
888
889 xx += SHR32(pxx, 10);
890 xy += SHR32(pxy, 10);
891 yy += SHR32(pyy, 10);
892 }
893 mem->XX += MULT16_32_Q15(short_alpha, xx-mem->XX);
894 mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY);
895 mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY);
896 mem->XX = MAX32(0, mem->XX);
897 mem->XY = MAX32(0, mem->XY);
898 mem->YY = MAX32(0, mem->YY);
899 if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18))
900 {
901 sqrt_xx = celt_sqrt(mem->XX);
902 sqrt_yy = celt_sqrt(mem->YY);
903 qrrt_xx = celt_sqrt(sqrt_xx);
904 qrrt_yy = celt_sqrt(sqrt_yy);
905 /* Inter-channel correlation */
906 mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy);
907 corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16);
908 /* Approximate loudness difference */
909 ldiff = Q15ONE*ABS16(qrrt_xx-qrrt_yy)/(EPSILON+qrrt_xx+qrrt_yy);
910 width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff);
911 /* Smoothing over one second */
912 mem->smoothed_width += (width-mem->smoothed_width)/frame_rate;
913 /* Peak follower */
914 mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width);
915 } else {
916 width = 0;
917 corr=Q15ONE;
918 ldiff=0;
919 }
920 /*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/
921 return EXTRACT16(MIN32(Q15ONE,20*mem->max_follower));
922}
923
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500924opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400925 unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400926 const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, int analysis_channels, downmix_func downmix)
Jean-Marc Valin3e66e912010-06-30 14:16:14 -0400927{
Ralph Giles641eea82011-08-02 10:06:59 -0700928 void *silk_enc;
929 CELTEncoder *celt_enc;
Jean-Marc Valine2d1ef12010-07-06 15:39:19 -0400930 int i;
Ralph Giles641eea82011-08-02 10:06:59 -0700931 int ret=0;
Jean-Marc Valin59354a72012-03-08 12:19:07 -0500932 opus_int32 nBytes;
Ralph Giles641eea82011-08-02 10:06:59 -0700933 ec_enc enc;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -0500934 int bytes_target;
Jean-Marc Valine3de5052011-02-20 12:23:48 -0500935 int prefill=0;
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -0500936 int start_band = 0;
Jean-Marc Valine2a09db2011-03-02 17:54:43 -0500937 int redundancy = 0;
Jean-Marc Valin6b459742012-09-20 22:00:22 -0400938 int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -0500939 int celt_to_silk = 0;
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400940 VARDECL(opus_val16, pcm_buf);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -0500941 int nb_compr_bytes;
942 int to_celt = 0;
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -0400943 opus_uint32 redundant_rng = 0;
Jean-Marc Valin957f7f12011-09-01 18:02:43 -0400944 int cutoff_Hz, hp_freq_smth1;
Jean-Marc Valin6b459742012-09-20 22:00:22 -0400945 int voice_est; /* Probability of voice in Q7 */
Jean-Marc Valinc681bd02011-09-02 14:47:26 -0400946 opus_int32 equiv_rate;
Jean-Marc Valind186c912011-09-08 15:13:46 -0400947 int delay_compensation;
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -0400948 int frame_rate;
Jean-Marc Valin6b459742012-09-20 22:00:22 -0400949 opus_int32 max_rate; /* Max bitrate we're allowed to use */
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -0400950 int curr_bandwidth;
Jean-Marc Valinf68799b2012-07-12 17:36:11 -0400951 opus_val16 HB_gain;
Jean-Marc Valin6b459742012-09-20 22:00:22 -0400952 opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -0500953 int total_buffer;
Jean-Marc Valind865fe62013-03-11 11:35:10 -0400954 opus_val16 stereo_width;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400955 const CELTMode *celt_mode;
956 AnalysisInfo analysis_info;
Jean-Marc Valin29254442013-09-28 19:29:23 -0400957 int analysis_read_pos_bak=-1;
958 int analysis_read_subframe_bak=-1;
Jean-Marc Valine22cc272011-10-14 13:48:17 -0400959 VARDECL(opus_val16, tmp_prefill);
960
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400961 ALLOC_STACK;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -0500962
Gregory Maxwelle7028172011-11-19 23:58:09 -0500963 max_data_bytes = IMIN(1276, out_data_bytes);
Jean-Marc Valin904e7a82011-09-11 14:29:46 -0400964
Jean-Marc Valin2b98bdf2011-08-20 00:21:46 -0400965 st->rangeFinal = 0;
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500966 if ((!st->variable_duration && 400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
Jean-Marc Valin23a900c2011-06-14 14:34:02 -0400967 50*frame_size != st->Fs && 25*frame_size != st->Fs && 50*frame_size != 3*st->Fs)
Jean-Marc Valin49583ed2012-11-22 13:11:43 -0500968 || (400*frame_size < st->Fs)
969 || max_data_bytes<=0
970 )
Jean-Marc Valin5609cec2011-12-13 14:52:43 -0500971 {
972 RESTORE_STACK;
973 return OPUS_BAD_ARG;
974 }
Jean-Marc Valin5095c472011-05-05 19:47:48 -0400975 silk_enc = (char*)st+st->silk_enc_offset;
976 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -0400977 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
Jean-Marc Valind186c912011-09-08 15:13:46 -0400978 delay_compensation = 0;
979 else
980 delay_compensation = st->delay_compensation;
Jean-Marc Valinba547462011-05-10 17:54:41 -0400981
982 lsb_depth = IMIN(lsb_depth, st->lsb_depth);
Jean-Marc Valin103302b2011-05-19 17:17:44 -0400983
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400984 analysis_info.valid = 0;
985 celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400986#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5645f52013-09-16 14:36:53 -0400987#ifdef FIXED_POINT
Jean-Marc Valin29254442013-09-28 19:29:23 -0400988 if (st->silk_mode.complexity >= 10 && st->Fs==48000)
Jean-Marc Valinf5645f52013-09-16 14:36:53 -0400989#else
Jean-Marc Valin29254442013-09-28 19:29:23 -0400990 if (st->silk_mode.complexity >= 7 && st->Fs==48000)
Jean-Marc Valinf5645f52013-09-16 14:36:53 -0400991#endif
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400992 {
Jean-Marc Valin29254442013-09-28 19:29:23 -0400993 analysis_read_pos_bak = st->analysis.read_pos;
994 analysis_read_subframe_bak = st->analysis.read_subframe;
Jean-Marc Valina4c25122013-09-28 17:22:41 -0400995 run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400996 c1, c2, analysis_channels, st->Fs,
997 lsb_depth, downmix, &analysis_info);
Jean-Marc Valina4c25122013-09-28 17:22:41 -0400998 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400999#endif
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001000
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001001 st->voice_ratio = -1;
1002
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -04001003#ifndef DISABLE_FLOAT_API
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001004 st->detected_bandwidth = 0;
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001005 if (analysis_info.valid)
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001006 {
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001007 int analysis_bandwidth;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001008 if (st->signal_type == OPUS_AUTO)
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001009 st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob));
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001010
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001011 analysis_bandwidth = analysis_info.bandwidth;
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001012 if (analysis_bandwidth<=12)
1013 st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
1014 else if (analysis_bandwidth<=14)
1015 st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
1016 else if (analysis_bandwidth<=16)
1017 st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1018 else if (analysis_bandwidth<=18)
1019 st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
1020 else
1021 st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001022 }
Jean-Marc Valin862e1822010-07-20 12:19:00 -04001023#endif
Jean-Marc Valin7ebacf42012-11-13 02:24:07 -05001024
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001025 if (st->channels==2 && st->force_channels!=1)
1026 stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem);
1027 else
1028 stereo_width = 0;
Jean-Marc Valin7ebacf42012-11-13 02:24:07 -05001029 total_buffer = delay_compensation;
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001030 st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001031
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -04001032 frame_rate = st->Fs/frame_size;
Jean-Marc Valin5609cec2011-12-13 14:52:43 -05001033 if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
1034 || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
1035 {
Gregory Maxwell31e8a842012-07-18 10:06:01 -04001036 /*If the space is too low to do something useful, emit 'PLC' frames.*/
Jean-Marc Valin5609cec2011-12-13 14:52:43 -05001037 int tocmode = st->mode;
Gregory Maxwell31e8a842012-07-18 10:06:01 -04001038 int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth;
Jean-Marc Valin5609cec2011-12-13 14:52:43 -05001039 if (tocmode==0)
1040 tocmode = MODE_SILK_ONLY;
1041 if (frame_rate>100)
1042 tocmode = MODE_CELT_ONLY;
1043 if (frame_rate < 50)
1044 tocmode = MODE_SILK_ONLY;
Gregory Maxwell31e8a842012-07-18 10:06:01 -04001045 if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND)
1046 bw=OPUS_BANDWIDTH_WIDEBAND;
1047 else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
1048 bw=OPUS_BANDWIDTH_NARROWBAND;
1049 else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
1050 bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
1051 data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
Jean-Marc Valin5609cec2011-12-13 14:52:43 -05001052 RESTORE_STACK;
1053 return 1;
1054 }
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001055 if (!st->use_vbr)
1056 {
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -04001057 int cbrBytes;
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001058 cbrBytes = IMIN( (st->bitrate_bps + 4*frame_rate)/(8*frame_rate) , max_data_bytes);
1059 st->bitrate_bps = cbrBytes * (8*frame_rate);
1060 max_data_bytes = cbrBytes;
1061 }
Koen Vos43a0de42011-10-24 09:10:58 -04001062 max_rate = frame_rate*max_data_bytes*8;
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001063
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001064 /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001065 equiv_rate = st->bitrate_bps - (40*st->channels+20)*(st->Fs/frame_size - 50);
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001066
1067 if (st->signal_type == OPUS_SIGNAL_VOICE)
1068 voice_est = 127;
1069 else if (st->signal_type == OPUS_SIGNAL_MUSIC)
1070 voice_est = 0;
1071 else if (st->voice_ratio >= 0)
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001072 {
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001073 voice_est = st->voice_ratio*327>>8;
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001074 /* For AUDIO, never be more than 90% confident of having speech */
1075 if (st->application == OPUS_APPLICATION_AUDIO)
1076 voice_est = IMIN(voice_est, 115);
1077 } else if (st->application == OPUS_APPLICATION_VOIP)
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001078 voice_est = 115;
1079 else
Jean-Marc Valin9dc0e402011-10-24 20:26:29 -04001080 voice_est = 48;
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001081
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001082 if (st->force_channels!=OPUS_AUTO && st->channels == 2)
Koen Vos479e18b2011-05-25 23:09:52 -04001083 {
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001084 st->stream_channels = st->force_channels;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001085 } else {
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001086#ifdef FUZZING
1087 /* Random mono/stereo decision */
1088 if (st->channels == 2 && (rand()&0x1F)==0)
1089 st->stream_channels = 3-st->stream_channels;
1090#else
1091 /* Rate-dependent mono-stereo decision */
1092 if (st->channels == 2)
1093 {
1094 opus_int32 stereo_threshold;
1095 stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14);
1096 if (st->stream_channels == 2)
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001097 stereo_threshold -= 1000;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001098 else
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001099 stereo_threshold += 1000;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001100 st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1;
1101 } else {
1102 st->stream_channels = st->channels;
1103 }
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001104#endif
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001105 }
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001106 equiv_rate = st->bitrate_bps - (40*st->stream_channels+20)*(st->Fs/frame_size - 50);
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001107
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04001108 /* Mode selection depending on application and signal type */
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -04001109 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
Jean-Marc Valind186c912011-09-08 15:13:46 -04001110 {
1111 st->mode = MODE_CELT_ONLY;
1112 } else if (st->user_forced_mode == OPUS_AUTO)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001113 {
Jean-Marc Valin9fd13d62011-10-07 22:50:49 -04001114#ifdef FUZZING
1115 /* Random mode switching */
1116 if ((rand()&0xF)==0)
1117 {
1118 if ((rand()&0x1)==0)
1119 st->mode = MODE_CELT_ONLY;
1120 else
1121 st->mode = MODE_SILK_ONLY;
1122 } else {
1123 if (st->prev_mode==MODE_CELT_ONLY)
1124 st->mode = MODE_CELT_ONLY;
1125 else
1126 st->mode = MODE_SILK_ONLY;
1127 }
1128#else
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001129 opus_int32 mode_voice, mode_music;
1130 opus_int32 threshold;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001131
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001132 /* Interpolate based on stereo width */
Jean-Marc Valin16ba19a2013-06-27 03:40:44 -04001133 mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0])
1134 + MULT16_32_Q15(stereo_width,mode_thresholds[1][0]));
1135 mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1])
1136 + MULT16_32_Q15(stereo_width,mode_thresholds[1][1]));
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001137 /* Interpolate based on speech/music probability */
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001138 threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14);
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001139 /* Bias towards SILK for VoIP because of some useful features */
1140 if (st->application == OPUS_APPLICATION_VOIP)
1141 threshold += 8000;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04001142
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001143 /*printf("%f %d\n", stereo_width/(float)Q15ONE, threshold);*/
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001144 /* Hysteresis */
1145 if (st->prev_mode == MODE_CELT_ONLY)
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001146 threshold -= 4000;
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001147 else if (st->prev_mode>0)
Jean-Marc Valind865fe62013-03-11 11:35:10 -04001148 threshold += 4000;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04001149
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001150 st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY;
Jean-Marc Valin9dc0e402011-10-24 20:26:29 -04001151
Jean-Marc Valin6ef37872011-10-27 13:39:12 -04001152 /* When FEC is enabled and there's enough packet loss, use SILK */
Jean-Marc Valin9dc0e402011-10-24 20:26:29 -04001153 if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)
1154 st->mode = MODE_SILK_ONLY;
Jean-Marc Valin6ef37872011-10-27 13:39:12 -04001155 /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */
1156 if (st->silk_mode.useDTX && voice_est > 100)
1157 st->mode = MODE_SILK_ONLY;
Jean-Marc Valin9fd13d62011-10-07 22:50:49 -04001158#endif
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001159 } else {
1160 st->mode = st->user_forced_mode;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04001161 }
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001162
Jean-Marc Valin81936d52011-08-13 01:44:39 -04001163 /* Override the chosen mode to make sure we meet the requested frame size */
Jean-Marc Valin81936d52011-08-13 01:44:39 -04001164 if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100)
1165 st->mode = MODE_CELT_ONLY;
Jean-Marc Valinc6d0c432013-10-14 17:33:53 -04001166 if (st->lfe)
1167 st->mode = MODE_CELT_ONLY;
Jean-Marc Valin81936d52011-08-13 01:44:39 -04001168
Jean-Marc Valin9fd13d62011-10-07 22:50:49 -04001169 if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
1170 && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
1171 {
1172 /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
1173 st->silk_mode.toMono = 1;
1174 st->stream_channels = 2;
1175 } else {
1176 st->silk_mode.toMono = 0;
1177 }
1178
Jean-Marc Valin68545562011-08-12 00:30:47 -04001179 if (st->prev_mode > 0 &&
1180 ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
1181 (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
1182 {
1183 redundancy = 1;
1184 celt_to_silk = (st->mode != MODE_CELT_ONLY);
1185 if (!celt_to_silk)
1186 {
1187 /* Switch to SILK/hybrid if frame size is 10 ms or more*/
1188 if (frame_size >= st->Fs/100)
1189 {
1190 st->mode = st->prev_mode;
1191 to_celt = 1;
1192 } else {
1193 redundancy=0;
1194 }
1195 }
1196 }
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001197 /* For the first frame at a new SILK bandwidth */
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001198 if (st->silk_bw_switch)
1199 {
1200 redundancy = 1;
1201 celt_to_silk = 1;
1202 st->silk_bw_switch = 0;
Jean-Marc Valinf982b842013-03-11 16:25:44 -04001203 prefill=1;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001204 }
1205
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001206 if (redundancy)
1207 {
1208 /* Fair share of the max size allowed */
1209 redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200));
1210 /* For VBR, target the actual bitrate (subject to the limit above) */
1211 if (st->use_vbr)
1212 redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600);
1213 }
1214
Jean-Marc Valin68545562011-08-12 00:30:47 -04001215 if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
1216 {
1217 silk_EncControlStruct dummy;
1218 silk_InitEncoder( silk_enc, &dummy);
1219 prefill=1;
1220 }
1221
Jean-Marc Valin243ff0c2011-05-03 17:06:54 -04001222 /* Automatic (rate-dependent) bandwidth selection */
Jean-Marc Valin09c67662011-05-04 22:34:53 -04001223 if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001224 {
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001225 const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;
1226 opus_int32 bandwidth_thresholds[8];
Ralph Giles641eea82011-08-02 10:06:59 -07001227 int bandwidth = OPUS_BANDWIDTH_FULLBAND;
Jean-Marc Valinbfad2812011-10-25 13:46:35 -04001228 opus_int32 equiv_rate2;
Jean-Marc Valin09c67662011-05-04 22:34:53 -04001229
Jean-Marc Valinbfad2812011-10-25 13:46:35 -04001230 equiv_rate2 = equiv_rate;
1231 if (st->mode != MODE_CELT_ONLY)
1232 {
1233 /* Adjust the threshold +/- 10% depending on complexity */
1234 equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50;
1235 /* CBR is less efficient by ~1 kb/s */
1236 if (!st->use_vbr)
1237 equiv_rate2 -= 1000;
1238 }
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001239 if (st->channels==2 && st->force_channels!=1)
Jean-Marc Valinc681bd02011-09-02 14:47:26 -04001240 {
1241 voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
1242 music_bandwidth_thresholds = stereo_music_bandwidth_thresholds;
1243 } else {
1244 voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds;
1245 music_bandwidth_thresholds = mono_music_bandwidth_thresholds;
1246 }
1247 /* Interpolate bandwidth thresholds depending on voice estimation */
1248 for (i=0;i<8;i++)
1249 {
1250 bandwidth_thresholds[i] = music_bandwidth_thresholds[i]
1251 + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14);
1252 }
Ralph Giles641eea82011-08-02 10:06:59 -07001253 do {
1254 int threshold, hysteresis;
1255 threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)];
1256 hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1];
1257 if (!st->first)
1258 {
1259 if (st->bandwidth >= bandwidth)
1260 threshold -= hysteresis;
1261 else
1262 threshold += hysteresis;
1263 }
Jean-Marc Valinbfad2812011-10-25 13:46:35 -04001264 if (equiv_rate2 >= threshold)
Ralph Giles641eea82011-08-02 10:06:59 -07001265 break;
1266 } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
1267 st->bandwidth = bandwidth;
1268 /* Prevents any transition to SWB/FB until the SILK layer has fully
1269 switched to WB mode and turned the variable LP filter off */
Jean-Marc Valine1be1922011-11-28 22:48:01 -05001270 if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
Ralph Giles641eea82011-08-02 10:06:59 -07001271 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001272 }
Jean-Marc Valin955f94c2011-03-08 22:12:43 -05001273
Jean-Marc Valin9ba17432011-10-24 22:41:18 -04001274 if (st->bandwidth>st->max_bandwidth)
1275 st->bandwidth = st->max_bandwidth;
1276
Jean-Marc Valinefe16c52011-09-29 22:02:37 -04001277 if (st->user_bandwidth != OPUS_AUTO)
1278 st->bandwidth = st->user_bandwidth;
1279
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -04001280 /* This prevents us from using hybrid at unsafe CBR/max rates */
1281 if (st->mode != MODE_CELT_ONLY && max_rate < 15000)
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001282 {
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -04001283 st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND);
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001284 }
1285
Jean-Marc Valin243ff0c2011-05-03 17:06:54 -04001286 /* Prevents Opus from wasting bits on frequencies that are above
1287 the Nyquist rate of the input signal */
Jean-Marc Valin541df0a2011-05-26 00:22:58 -04001288 if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND)
Ralph Giles641eea82011-08-02 10:06:59 -07001289 st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -04001290 if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
Ralph Giles641eea82011-08-02 10:06:59 -07001291 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -04001292 if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND)
Ralph Giles641eea82011-08-02 10:06:59 -07001293 st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -04001294 if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND)
Ralph Giles641eea82011-08-02 10:06:59 -07001295 st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001296#ifndef DISABLE_FLOAT_API
Jean-Marc Valin3ecd9c22013-02-19 00:42:15 -05001297 /* Use detected bandwidth to reduce the encoded bandwidth. */
Jean-Marc Valin23fcd702012-12-21 13:09:43 -05001298 if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO)
Jean-Marc Valin7509fdb2012-12-20 22:48:35 -05001299 {
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001300 int min_detected_bandwidth;
1301 /* Makes bandwidth detection more conservative just in case the detector
1302 gets it wrong when we could have coded a high bandwidth transparently.
1303 When operating in SILK/hybrid mode, we don't go below wideband to avoid
1304 more complicated switches that require redundancy. */
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001305 if (equiv_rate <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY)
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001306 min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001307 else if (equiv_rate <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY)
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001308 min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001309 else if (equiv_rate <= 30000*st->stream_channels)
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001310 min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001311 else if (equiv_rate <= 44000*st->stream_channels)
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001312 min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
Jean-Marc Valin3ecd9c22013-02-19 00:42:15 -05001313 else
Jean-Marc Valin278389d2013-05-17 02:03:33 -04001314 min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
1315
1316 st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth);
1317 st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);
Jean-Marc Valin7509fdb2012-12-20 22:48:35 -05001318 }
1319#endif
Jean-Marc Valinb3eba242012-12-20 23:11:53 -05001320 celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth));
Jean-Marc Valin955f94c2011-03-08 22:12:43 -05001321
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001322 /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -04001323 if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8))
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001324 st->mode = MODE_CELT_ONLY;
Jean-Marc Valin955f94c2011-03-08 22:12:43 -05001325
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001326 /* CELT mode doesn't support mediumband, use wideband instead */
1327 if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
1328 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04001329 if (st->lfe)
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04001330 st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001331
Jean-Marc Valin81936d52011-08-13 01:44:39 -04001332 /* Can't support higher than wideband for >20 ms frames */
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001333 if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND))
1334 {
Jean-Marc Valind970a852011-09-08 21:41:29 -04001335 VARDECL(unsigned char, tmp_data);
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001336 int nb_frames;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001337 int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
Timothy B. Terriberryc152d602013-05-08 10:32:37 -07001338 VARDECL(OpusRepacketizer, rp);
Gregory Maxwelle7028172011-11-19 23:58:09 -05001339 opus_int32 bytes_per_frame;
Jean-Marc Valinc5635d22013-11-13 14:08:22 -05001340 opus_int32 repacketize_len;
Jean-Marc Valind970a852011-09-08 21:41:29 -04001341
Jean-Marc Valinc2b34412013-10-28 21:48:50 -04001342#ifndef DISABLE_FLOAT_API
Jean-Marc Valin29254442013-09-28 19:29:23 -04001343 if (analysis_read_pos_bak!= -1)
1344 {
1345 st->analysis.read_pos = analysis_read_pos_bak;
1346 st->analysis.read_subframe = analysis_read_subframe_bak;
1347 }
Jean-Marc Valinc2b34412013-10-28 21:48:50 -04001348#endif
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001349
Jean-Marc Valind970a852011-09-08 21:41:29 -04001350 nb_frames = frame_size > st->Fs/25 ? 3 : 2;
Gregory Maxwelle7028172011-11-19 23:58:09 -05001351 bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);
Jean-Marc Valind970a852011-09-08 21:41:29 -04001352
1353 ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
Jean-Marc Valind970a852011-09-08 21:41:29 -04001354
Timothy B. Terriberryc152d602013-05-08 10:32:37 -07001355 ALLOC(rp, 1, OpusRepacketizer);
1356 opus_repacketizer_init(rp);
Jean-Marc Valind3358b12011-06-14 14:48:53 -04001357
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001358 bak_mode = st->user_forced_mode;
1359 bak_bandwidth = st->user_bandwidth;
1360 bak_channels = st->force_channels;
1361
1362 st->user_forced_mode = st->mode;
1363 st->user_bandwidth = st->bandwidth;
1364 st->force_channels = st->stream_channels;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001365 bak_to_mono = st->silk_mode.toMono;
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001366
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001367 if (bak_to_mono)
1368 st->force_channels = 1;
1369 else
1370 st->prev_channels = st->stream_channels;
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001371 for (i=0;i<nb_frames;i++)
1372 {
1373 int tmp_len;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001374 st->silk_mode.toMono = 0;
Jean-Marc Valin7ef6c7c2011-10-17 14:20:43 -04001375 /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
1376 if (to_celt && i==nb_frames-1)
1377 st->user_forced_mode = MODE_CELT_ONLY;
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001378 tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50,
1379 tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001380 NULL, 0, c1, c2, analysis_channels, downmix);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001381 if (tmp_len<0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001382 {
1383 RESTORE_STACK;
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001384 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001385 }
Timothy B. Terriberryc152d602013-05-08 10:32:37 -07001386 ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001387 if (ret<0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001388 {
1389 RESTORE_STACK;
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001390 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001391 }
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001392 }
Jean-Marc Valinc5635d22013-11-13 14:08:22 -05001393 if (st->use_vbr)
1394 repacketize_len = out_data_bytes;
1395 else
1396 repacketize_len = IMIN(3*st->bitrate_bps/(3*8*50/nb_frames), out_data_bytes);
1397 ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001398 if (ret<0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001399 {
1400 RESTORE_STACK;
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001401 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001402 }
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001403 st->user_forced_mode = bak_mode;
1404 st->user_bandwidth = bak_bandwidth;
1405 st->force_channels = bak_channels;
Jean-Marc Valin1e22a4b2011-10-07 22:29:38 -04001406 st->silk_mode.toMono = bak_to_mono;
Jean-Marc Valine4336a52011-09-08 18:19:50 -04001407 RESTORE_STACK;
1408 return ret;
1409 }
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001410 curr_bandwidth = st->bandwidth;
Jean-Marc Valin81936d52011-08-13 01:44:39 -04001411
1412 /* Chooses the appropriate mode for speech
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04001413 *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001414 if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001415 st->mode = MODE_HYBRID;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001416 if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05001417 st->mode = MODE_SILK_ONLY;
1418
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001419 /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001420 bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001421
Ralph Giles641eea82011-08-02 10:06:59 -07001422 data += 1;
Jean-Marc Valin606250a2011-02-15 14:31:21 -05001423
Ralph Giles641eea82011-08-02 10:06:59 -07001424 ec_enc_init(&enc, data, max_data_bytes-1);
Jean-Marc Valin24af3032010-06-30 14:29:45 -04001425
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001426 ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16);
1427 for (i=0;i<total_buffer*st->channels;i++)
1428 pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels+i];
Jean-Marc Valin957f7f12011-09-01 18:02:43 -04001429
1430 if (st->mode == MODE_CELT_ONLY)
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -07001431 hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -04001432 else
1433 hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15;
1434
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -07001435 st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15,
Jean-Marc Valin957f7f12011-09-01 18:02:43 -04001436 hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) );
1437
1438 /* convert from log scale to Hertz */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -07001439 cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) );
Jean-Marc Valin957f7f12011-09-01 18:02:43 -04001440
1441 if (st->application == OPUS_APPLICATION_VOIP)
1442 {
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001443 hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
Jean-Marc Valin957f7f12011-09-01 18:02:43 -04001444 } else {
Jean-Marc Valindb13c382011-12-23 11:58:43 -05001445 dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
Jean-Marc Valin957f7f12011-09-01 18:02:43 -04001446 }
Jean-Marc Valin2f0ca762011-09-01 16:56:40 -04001447
Jean-Marc Valin7ebacf42012-11-13 02:24:07 -05001448
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001449
Ralph Giles641eea82011-08-02 10:06:59 -07001450 /* SILK processing */
Jean-Marc Valinf68799b2012-07-12 17:36:11 -04001451 HB_gain = Q15ONE;
Jean-Marc Valin606250a2011-02-15 14:31:21 -05001452 if (st->mode != MODE_CELT_ONLY)
1453 {
Jean-Marc Valinf68799b2012-07-12 17:36:11 -04001454 opus_int32 total_bitRate, celt_rate;
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001455#ifdef FIXED_POINT
1456 const opus_int16 *pcm_silk;
1457#else
1458 VARDECL(opus_int16, pcm_silk);
1459 ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
1460#endif
Koen Vos0b00b312012-07-12 14:55:49 -04001461
1462 /* Distribute bits between SILK and CELT */
1463 total_bitRate = 8 * bytes_target * frame_rate;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001464 if( st->mode == MODE_HYBRID ) {
Jean-Marc Valinf68799b2012-07-12 17:36:11 -04001465 int HB_gain_ref;
Koen Vos0b00b312012-07-12 14:55:49 -04001466 /* Base rate for SILK */
1467 st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) );
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001468 if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {
Koen Vos0b00b312012-07-12 14:55:49 -04001469 /* SILK gets 2/3 of the remaining bits */
1470 st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3;
1471 } else { /* FULLBAND */
1472 /* SILK gets 3/5 of the remaining bits */
1473 st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5;
Karsten Vandborg Sorensen78054752011-02-03 09:36:59 -05001474 }
Koen Vos0b00b312012-07-12 14:55:49 -04001475 /* Don't let SILK use more than 80% */
1476 if( st->silk_mode.bitRate > total_bitRate * 4/5 ) {
1477 st->silk_mode.bitRate = total_bitRate * 4/5;
Koen Vos03c1d662011-02-17 16:54:44 -05001478 }
Koen Vos0b00b312012-07-12 14:55:49 -04001479 /* Increasingly attenuate high band when it gets allocated fewer bits */
1480 celt_rate = total_bitRate - st->silk_mode.bitRate;
Koen Vos933a2752013-03-11 13:30:47 -04001481 HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;
1482 HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);
1483 HB_gain = HB_gain < Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;
Koen Vos0b00b312012-07-12 14:55:49 -04001484 } else {
1485 /* SILK gets all bits */
1486 st->silk_mode.bitRate = total_bitRate;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001487 }
Jean-Marc Valin862e1822010-07-20 12:19:00 -04001488
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -04001489 /* Surround masking for SILK */
1490 if (st->energy_masking && st->use_vbr && !st->lfe)
1491 {
1492 opus_val32 mask_sum=0;
1493 opus_val16 masking_depth;
1494 opus_int32 rate_offset;
1495 int c;
1496 int end = 17;
1497 opus_int16 srate = 16000;
1498 if (st->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
1499 {
1500 end = 13;
1501 srate = 8000;
1502 } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
1503 {
1504 end = 15;
1505 srate = 12000;
1506 }
1507 for (c=0;c<st->channels;c++)
1508 {
1509 for(i=0;i<end;i++)
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001510 {
1511 opus_val16 mask;
1512 mask = MAX16(MIN16(st->energy_masking[21*c+i],
1513 QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));
1514 if (mask > 0)
1515 mask = HALF16(mask);
1516 mask_sum += mask;
1517 }
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -04001518 }
1519 /* Conservative rate reduction, we cut the masking in half */
1520 masking_depth = HALF16(mask_sum / end*st->channels);
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -04001521 rate_offset = PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT);
1522 rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3);
Jean-Marc Valin36a21ed2013-09-14 15:46:09 -04001523 rate_offset += QCONST16(.4f, DB_SHIFT);
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -04001524 st->silk_mode.bitRate += rate_offset;
1525 bytes_target += rate_offset * frame_size / (8 * st->Fs);
1526 }
1527
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001528 st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001529 st->silk_mode.nChannelsAPI = st->channels;
1530 st->silk_mode.nChannelsInternal = st->stream_channels;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001531 if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
Ralph Giles641eea82011-08-02 10:06:59 -07001532 st->silk_mode.desiredInternalSampleRate = 8000;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001533 } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
Ralph Giles641eea82011-08-02 10:06:59 -07001534 st->silk_mode.desiredInternalSampleRate = 12000;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001535 } else {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001536 silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
Jean-Marc Valind8f90972011-04-27 10:06:53 -04001537 st->silk_mode.desiredInternalSampleRate = 16000;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001538 }
1539 if( st->mode == MODE_HYBRID ) {
1540 /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
Koen Vos1e1562c2011-02-14 15:04:59 -05001541 st->silk_mode.minInternalSampleRate = 16000;
1542 } else {
1543 st->silk_mode.minInternalSampleRate = 8000;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001544 }
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -04001545
1546 if (st->mode == MODE_SILK_ONLY)
1547 {
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -04001548 opus_int32 effective_max_rate = max_rate;
Jean-Marc Valine1be1922011-11-28 22:48:01 -05001549 st->silk_mode.maxInternalSampleRate = 16000;
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -04001550 if (frame_rate > 50)
1551 effective_max_rate = effective_max_rate*2/3;
1552 if (effective_max_rate < 13000)
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -04001553 {
1554 st->silk_mode.maxInternalSampleRate = 12000;
1555 st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate);
1556 }
Jean-Marc Valin33bd6aa2011-10-24 11:53:01 -04001557 if (effective_max_rate < 9600)
Jean-Marc Valin99ca4b32011-10-20 14:30:30 -04001558 {
1559 st->silk_mode.maxInternalSampleRate = 8000;
1560 st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate);
1561 }
1562 } else {
1563 st->silk_mode.maxInternalSampleRate = 16000;
1564 }
Jean-Marc Valinb5be8262010-11-12 06:47:46 +08001565
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001566 st->silk_mode.useCBR = !st->use_vbr;
1567
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001568 /* Call SILK encoder for the low band */
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001569 nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001570
1571 st->silk_mode.maxBits = nBytes*8;
1572 /* Only allow up to 90% of the bits for hybrid mode*/
1573 if (st->mode == MODE_HYBRID)
1574 st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10;
1575 if (st->silk_mode.useCBR)
1576 {
1577 st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8;
1578 /* Reduce the initial target to make it easier to reach the CBR rate */
Jean-Marc Valind17bc2e2011-10-27 16:46:34 -04001579 st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001580 }
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001581
Jean-Marc Valine3de5052011-02-20 12:23:48 -05001582 if (prefill)
Jean-Marc Valina93f5012011-03-03 15:50:08 -05001583 {
Jean-Marc Valin59354a72012-03-08 12:19:07 -05001584 opus_int32 zero=0;
Jean-Marc Valin61e9eb12013-02-06 18:10:51 -05001585 int prefill_offset;
Jean-Marc Valin61e9eb12013-02-06 18:10:51 -05001586 /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode
1587 a discontinuity. The exact location is what we need to avoid leaving any "gap"
1588 in the audio when mixing with the redundant CELT frame. Here we can afford to
1589 overwrite st->delay_buffer because the only thing that uses it before it gets
1590 rewritten is tmp_prefill[] and even then only the part after the ramp really
1591 gets used (rather than sent to the encoder and discarded) */
1592 prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400);
1593 gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset,
1594 0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs);
1595 for(i=0;i<prefill_offset;i++)
1596 st->delay_buffer[i]=0;
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001597#ifdef FIXED_POINT
1598 pcm_silk = st->delay_buffer;
1599#else
1600 for (i=0;i<st->encoder_buffer*st->channels;i++)
Ralph Giles04cca282011-08-24 00:29:29 -04001601 pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001602#endif
1603 silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 );
Jean-Marc Valina93f5012011-03-03 15:50:08 -05001604 }
Jean-Marc Valine3de5052011-02-20 12:23:48 -05001605
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001606#ifdef FIXED_POINT
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001607 pcm_silk = pcm_buf+total_buffer*st->channels;
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001608#else
1609 for (i=0;i<frame_size*st->channels;i++)
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001610 pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]);
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001611#endif
1612 ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001613 if( ret ) {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001614 /*fprintf (stderr, "SILK encode error: %d\n", ret);*/
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001615 /* Handle error */
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001616 RESTORE_STACK;
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001617 return OPUS_INTERNAL_ERROR;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001618 }
Jean-Marc Valin617fcd22011-03-16 22:11:53 -04001619 if (nBytes==0)
Jean-Marc Valin421a6282011-08-18 14:32:16 -04001620 {
Jean-Marc Valine1be1922011-11-28 22:48:01 -05001621 st->rangeFinal = 0;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001622 data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
Jean-Marc Valin44e27dd2011-08-29 23:35:17 -04001623 RESTORE_STACK;
Jean-Marc Valin421a6282011-08-18 14:32:16 -04001624 return 1;
1625 }
Jean-Marc Valin69bfc672011-08-29 21:46:17 -04001626 /* Extract SILK internal bandwidth for signaling in first byte */
1627 if( st->mode == MODE_SILK_ONLY ) {
1628 if( st->silk_mode.internalSampleRate == 8000 ) {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001629 curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
Jean-Marc Valin69bfc672011-08-29 21:46:17 -04001630 } else if( st->silk_mode.internalSampleRate == 12000 ) {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001631 curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
Jean-Marc Valin69bfc672011-08-29 21:46:17 -04001632 } else if( st->silk_mode.internalSampleRate == 16000 ) {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001633 curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
Jean-Marc Valin69bfc672011-08-29 21:46:17 -04001634 }
1635 } else {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -07001636 silk_assert( st->silk_mode.internalSampleRate == 16000 );
Jean-Marc Valin69bfc672011-08-29 21:46:17 -04001637 }
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001638
1639 st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001640 /* FIXME: How do we allocate the redundancy for CBR? */
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001641 if (st->silk_mode.opusCanSwitch)
1642 {
1643 redundancy = 1;
1644 celt_to_silk = 0;
1645 st->silk_bw_switch = 1;
1646 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001647 }
Jean-Marc Valin67008d22010-07-20 11:13:30 -04001648
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001649 /* CELT processing */
Ralph Giles641eea82011-08-02 10:06:59 -07001650 {
1651 int endband=21;
Jean-Marc Valine2d1ef12010-07-06 15:39:19 -04001652
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001653 switch(curr_bandwidth)
Ralph Giles641eea82011-08-02 10:06:59 -07001654 {
1655 case OPUS_BANDWIDTH_NARROWBAND:
1656 endband = 13;
1657 break;
1658 case OPUS_BANDWIDTH_MEDIUMBAND:
Ralph Giles04cca282011-08-24 00:29:29 -04001659 case OPUS_BANDWIDTH_WIDEBAND:
1660 endband = 17;
1661 break;
Ralph Giles641eea82011-08-02 10:06:59 -07001662 case OPUS_BANDWIDTH_SUPERWIDEBAND:
1663 endband = 19;
1664 break;
1665 case OPUS_BANDWIDTH_FULLBAND:
1666 endband = 21;
1667 break;
1668 }
1669 celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband));
1670 celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels));
1671 }
Jean-Marc Valin23f3a1f2011-10-30 22:41:32 -04001672 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
Ralph Giles641eea82011-08-02 10:06:59 -07001673 if (st->mode != MODE_SILK_ONLY)
1674 {
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001675 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001676 /* Allow prediction unless we decide to disable it later */
1677 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2));
Jean-Marc Valine2a09db2011-03-02 17:54:43 -05001678
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001679 if (st->mode == MODE_HYBRID)
1680 {
1681 int len;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001682
Timothy B. Terriberrya1dd0fc2011-02-03 14:52:50 -08001683 len = (ec_tell(&enc)+7)>>3;
Jean-Marc Valin6d5af482011-10-08 22:45:19 -04001684 if (redundancy)
1685 len += st->mode == MODE_HYBRID ? 3 : 1;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001686 if( st->use_vbr ) {
Koen Vos5ad41a32011-02-04 00:49:48 -05001687 nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001688 } else {
1689 /* check if SILK used up too much */
1690 nb_compr_bytes = len > bytes_target ? len : bytes_target;
1691 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001692 } else {
Jean-Marc Valind9ad6e12011-02-01 18:08:41 -05001693 if (st->use_vbr)
1694 {
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05001695 opus_int32 bonus=0;
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -04001696#ifndef DISABLE_FLOAT_API
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001697 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50)
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05001698 {
Jean-Marc Valin3252bf22013-04-19 03:14:28 -04001699 bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50);
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001700 if (analysis_info.valid)
1701 bonus = (opus_int32)(bonus*(1.f+.5f*analysis_info.tonality));
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05001702 }
1703#endif
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001704 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
1705 celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05001706 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps+bonus));
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001707 nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
Jean-Marc Valind9ad6e12011-02-01 18:08:41 -05001708 } else {
1709 nb_compr_bytes = bytes_target;
1710 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05001711 }
1712
Ralph Giles641eea82011-08-02 10:06:59 -07001713 } else {
1714 nb_compr_bytes = 0;
1715 }
Jean-Marc Valinc8a20b72010-07-21 14:07:11 -04001716
Jean-Marc Valine22cc272011-10-14 13:48:17 -04001717 ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001718 if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0)
Jean-Marc Valine22cc272011-10-14 13:48:17 -04001719 {
1720 for (i=0;i<st->channels*st->Fs/400;i++)
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -05001721 tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels + i];
Jean-Marc Valine22cc272011-10-14 13:48:17 -04001722 }
1723
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001724 for (i=0;i<st->channels*(st->encoder_buffer-(frame_size+total_buffer));i++)
Jean-Marc Valin12c39922011-09-04 11:00:29 -04001725 st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size];
1726 for (;i<st->encoder_buffer*st->channels;i++)
Jean-Marc Valin1a2e7652011-11-06 23:27:16 -05001727 st->delay_buffer[i] = pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels+i];
Jean-Marc Valin2f0ca762011-09-01 16:56:40 -04001728
Jean-Marc Valinf68799b2012-07-12 17:36:11 -04001729 /* gain_fade() and stereo_fade() need to be after the buffer copying
1730 because we don't want any of this to affect the SILK part */
1731 if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) {
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -05001732 gain_fade(pcm_buf, pcm_buf,
Jean-Marc Valinf68799b2012-07-12 17:36:11 -04001733 st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs);
1734 }
1735 st->prev_HB_gain = HB_gain;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001736 if (st->mode != MODE_HYBRID || st->stream_channels==1)
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001737 st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),IMAX(0,equiv_rate-32000));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04001738 if( !st->energy_masking && st->channels == 2 ) {
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001739 /* Apply stereo width reduction (at low bitrates) */
1740 if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001741 opus_val16 g1, g2;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001742 g1 = st->hybrid_stereo_width_Q14;
Koen Vos854fe702011-10-09 20:34:41 -04001743 g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14);
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001744#ifdef FIXED_POINT
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001745 g1 = g1==16384 ? Q15ONE : SHL16(g1,1);
1746 g2 = g2==16384 ? Q15ONE : SHL16(g2,1);
Jean-Marc Valinab964572011-10-13 16:18:24 -04001747#else
Gregory Maxwell37f56592012-07-17 17:40:55 -04001748 g1 *= (1.f/16384);
1749 g2 *= (1.f/16384);
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001750#endif
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -05001751 stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap,
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001752 frame_size, st->channels, celt_mode->window, st->Fs);
Jean-Marc Valin103302b2011-05-19 17:17:44 -04001753 st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14;
1754 }
1755 }
1756
Jean-Marc Valine9b53212011-10-13 16:24:11 -04001757 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 -05001758 {
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001759 /* For SILK mode, the redundancy is inferred from the length */
Gregory Maxwelld9dd4992011-10-16 04:02:02 -04001760 if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes))
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001761 ec_enc_bit_logp(&enc, redundancy, 12);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001762 if (redundancy)
1763 {
Jean-Marc Valine5736ae2011-09-05 10:28:27 -04001764 int max_redundancy;
1765 ec_enc_bit_logp(&enc, celt_to_silk, 1);
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001766 if (st->mode == MODE_HYBRID)
Jean-Marc Valin8bbdf5f2013-11-13 17:50:39 -05001767 max_redundancy = (max_data_bytes-1)-nb_compr_bytes;
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001768 else
1769 max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001770 /* Target the same bit-rate for redundancy as for the rest,
1771 up to a max of 257 bytes */
Jean-Marc Valine5736ae2011-09-05 10:28:27 -04001772 redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600);
1773 redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001774 if (st->mode == MODE_HYBRID)
Ralph Giles04cca282011-08-24 00:29:29 -04001775 ec_enc_uint(&enc, redundancy_bytes-2, 256);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001776 }
Jean-Marc Valine5736ae2011-09-05 10:28:27 -04001777 } else {
1778 redundancy = 0;
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001779 }
1780
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001781 if (!redundancy)
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001782 {
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001783 st->silk_bw_switch = 0;
Jean-Marc Valin6b459742012-09-20 22:00:22 -04001784 redundancy_bytes = 0;
1785 }
Gregory Maxwell7d1df732011-09-05 11:28:28 -04001786 if (st->mode != MODE_CELT_ONLY)start_band=17;
1787
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001788 if (st->mode == MODE_SILK_ONLY)
1789 {
1790 ret = (ec_tell(&enc)+7)>>3;
1791 ec_enc_done(&enc);
1792 nb_compr_bytes = ret;
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001793 } else {
Jean-Marc Valin591b7492011-10-08 10:22:10 -04001794 nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001795 ec_enc_shrink(&enc, nb_compr_bytes);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001796 }
1797
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -04001798#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf8eb44e2013-05-17 23:22:09 -04001799 if (redundancy || st->mode != MODE_SILK_ONLY)
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001800 celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));
Jean-Marc Valinf8eb44e2013-05-17 23:22:09 -04001801#endif
Jean-Marc Valin51ac8e62011-08-15 22:06:02 -04001802
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001803 /* 5 ms redundant frame for CELT->SILK */
1804 if (redundancy && celt_to_silk)
1805 {
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001806 int err;
Jean-Marc Valin5095c472011-05-05 19:47:48 -04001807 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001808 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -05001809 err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001810 if (err < 0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001811 {
1812 RESTORE_STACK;
1813 return OPUS_INTERNAL_ERROR;
1814 }
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001815 celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
1816 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001817 }
1818
Jean-Marc Valin5095c472011-05-05 19:47:48 -04001819 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001820
1821 if (st->mode != MODE_SILK_ONLY)
Ralph Giles641eea82011-08-02 10:06:59 -07001822 {
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001823 if (st->mode != st->prev_mode && st->prev_mode > 0)
1824 {
1825 unsigned char dummy[2];
1826 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
1827
1828 /* Prefilling */
1829 celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
1830 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
1831 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001832 /* If false, we already busted the budget and we'll end up with a "PLC packet" */
Jean-Marc Valine1be1922011-11-28 22:48:01 -05001833 if (ec_tell(&enc) <= 8*nb_compr_bytes)
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001834 {
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -05001835 ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001836 if (ret < 0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001837 {
1838 RESTORE_STACK;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001839 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001840 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001841 }
Ralph Giles641eea82011-08-02 10:06:59 -07001842 }
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001843
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001844 /* 5 ms redundant frame for SILK->CELT */
1845 if (redundancy && !celt_to_silk)
1846 {
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001847 int err;
Jean-Marc Valine6a4ece2011-10-19 01:56:38 -04001848 unsigned char dummy[2];
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001849 int N2, N4;
1850 N2 = st->Fs/200;
1851 N4 = st->Fs/400;
1852
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001853 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
Jean-Marc Valin5095c472011-05-05 19:47:48 -04001854 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
1855 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001856
Jean-Marc Valin92675062011-09-11 22:00:46 -04001857 /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -05001858 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 -05001859
Jean-Marc Valinbb43b8b2012-12-17 18:02:56 -05001860 err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL);
Jean-Marc Valinf340bba2011-10-27 20:33:48 -04001861 if (err < 0)
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001862 {
1863 RESTORE_STACK;
1864 return OPUS_INTERNAL_ERROR;
1865 }
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001866 celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001867 }
1868
1869
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001870
Ralph Giles641eea82011-08-02 10:06:59 -07001871 /* Signalling the mode in the first byte */
1872 data--;
Jean-Marc Valin3b2aee02011-10-21 23:21:34 -04001873 data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
Jean-Marc Valin57de8a32010-09-07 17:37:56 -04001874
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -04001875 st->rangeFinal = enc.rng ^ redundant_rng;
Ralph Giles3f0962c2011-07-29 14:01:54 -07001876
Jean-Marc Valin0c0c5f92011-03-07 20:54:33 -05001877 if (to_celt)
1878 st->prev_mode = MODE_CELT_ONLY;
1879 else
1880 st->prev_mode = st->mode;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001881 st->prev_channels = st->stream_channels;
Gregory Maxwell220a7d42011-10-01 20:30:16 -04001882 st->prev_framesize = frame_size;
Jean-Marc Valinde3e16c2011-10-03 00:39:29 -04001883
Jean-Marc Valinc1673fa2011-04-28 08:04:20 -04001884 st->first = 0;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001885
1886 /* In the unlikely case that the SILK encoder busted its target, tell
1887 the decoder to call the PLC */
1888 if (ec_tell(&enc) > (max_data_bytes-1)*8)
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001889 {
Vincent Penquerc'h037918a2011-11-22 15:12:44 +00001890 if (max_data_bytes < 2)
1891 {
1892 RESTORE_STACK;
1893 return OPUS_BUFFER_TOO_SMALL;
1894 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001895 data[1] = 0;
1896 ret = 1;
1897 st->rangeFinal = 0;
Jean-Marc Valine1be1922011-11-28 22:48:01 -05001898 } else if (st->mode==MODE_SILK_ONLY&&!redundancy)
1899 {
1900 /*When in LPC only mode it's perfectly
1901 reasonable to strip off trailing zero bytes as
1902 the required range decoder behavior is to
1903 fill these in. This can't be done when the MDCT
1904 modes are used because the decoder needs to know
1905 the actual length for allocation purposes.*/
1906 while(ret>2&&data[ret]==0)ret--;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001907 }
1908 /* Count ToC and redundancy */
1909 ret += 1+redundancy_bytes;
1910 if (!st->use_vbr && ret >= 3)
1911 {
Jean-Marc Valinc5635d22013-11-13 14:08:22 -05001912 if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK)
1913
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001914 {
1915 RESTORE_STACK;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001916 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinc7921082012-03-05 19:56:13 -05001917 }
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001918 ret = max_data_bytes;
Jean-Marc Valin294bfec2011-10-20 00:39:41 -04001919 }
Jean-Marc Valin44e27dd2011-08-29 23:35:17 -04001920 RESTORE_STACK;
Jean-Marc Valinbe236b12011-10-29 02:12:26 -04001921 return ret;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04001922}
1923
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001924#ifdef FIXED_POINT
1925
1926#ifndef DISABLE_FLOAT_API
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001927opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
Gregory Maxwelle7028172011-11-19 23:58:09 -05001928 unsigned char *data, opus_int32 max_data_bytes)
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001929{
1930 int i, ret;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001931 int frame_size;
1932 int delay_compensation;
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001933 VARDECL(opus_int16, in);
1934 ALLOC_STACK;
1935
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001936 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
1937 delay_compensation = 0;
1938 else
1939 delay_compensation = st->delay_compensation;
1940 frame_size = compute_frame_size(pcm, analysis_frame_size,
1941 st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
1942 delay_compensation, downmix_float, st->analysis.subframe_mem);
1943
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001944 ALLOC(in, frame_size*st->channels, opus_int16);
1945
1946 for (i=0;i<frame_size*st->channels;i++)
1947 in[i] = FLOAT2INT16(pcm[i]);
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001948 ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_float);
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001949 RESTORE_STACK;
1950 return ret;
1951}
1952#endif
1953
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001954opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -05001955 unsigned char *data, opus_int32 out_data_bytes)
1956{
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001957 int frame_size;
1958 int delay_compensation;
1959 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
1960 delay_compensation = 0;
1961 else
1962 delay_compensation = st->delay_compensation;
1963 frame_size = compute_frame_size(pcm, analysis_frame_size,
1964 st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
Jean-Marc Valin88481712013-11-13 11:57:31 -05001965 delay_compensation, downmix_int
Jean-Marc Valinc2b34412013-10-28 21:48:50 -04001966#ifndef DISABLE_FLOAT_API
1967 , st->analysis.subframe_mem
1968#endif
1969 );
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001970 return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int);
Jean-Marc Valinb3eba242012-12-20 23:11:53 -05001971}
1972
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001973#else
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001974opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
Gregory Maxwelle7028172011-11-19 23:58:09 -05001975 unsigned char *data, opus_int32 max_data_bytes)
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001976{
1977 int i, ret;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001978 int frame_size;
1979 int delay_compensation;
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001980 VARDECL(float, in);
1981 ALLOC_STACK;
1982
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001983 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
1984 delay_compensation = 0;
1985 else
1986 delay_compensation = st->delay_compensation;
1987 frame_size = compute_frame_size(pcm, analysis_frame_size,
1988 st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
Jean-Marc Valin88481712013-11-13 11:57:31 -05001989 delay_compensation, downmix_int, st->analysis.subframe_mem);
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001990
Jean-Marc Valin6b9087a2013-09-28 23:51:11 -04001991 ALLOC(in, frame_size*st->channels, float);
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001992
Jean-Marc Valin6b9087a2013-09-28 23:51:11 -04001993 for (i=0;i<frame_size*st->channels;i++)
Koen Vos854fe702011-10-09 20:34:41 -04001994 in[i] = (1.0f/32768)*pcm[i];
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001995 ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int);
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001996 RESTORE_STACK;
1997 return ret;
1998}
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001999opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -05002000 unsigned char *data, opus_int32 out_data_bytes)
2001{
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04002002 int frame_size;
2003 int delay_compensation;
2004 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
2005 delay_compensation = 0;
2006 else
2007 delay_compensation = st->delay_compensation;
2008 frame_size = compute_frame_size(pcm, analysis_frame_size,
2009 st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
2010 delay_compensation, downmix_float, st->analysis.subframe_mem);
2011 return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24,
2012 pcm, analysis_frame_size, 0, -2, st->channels, downmix_float);
Jean-Marc Valinb3eba242012-12-20 23:11:53 -05002013}
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002014#endif
2015
2016
Jean-Marc Valin955f94c2011-03-08 22:12:43 -05002017int opus_encoder_ctl(OpusEncoder *st, int request, ...)
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002018{
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002019 int ret;
Ralph Giles641eea82011-08-02 10:06:59 -07002020 CELTEncoder *celt_enc;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002021 va_list ap;
2022
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002023 ret = OPUS_OK;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002024 va_start(ap, request);
2025
Jean-Marc Valin5095c472011-05-05 19:47:48 -04002026 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
2027
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002028 switch (request)
2029 {
Jean-Marc Valin69549ac2011-08-18 17:28:28 -04002030 case OPUS_SET_APPLICATION_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002031 {
Ralph Giles04cca282011-08-24 00:29:29 -04002032 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -04002033 if ( (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO
2034 && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
2035 || (!st->first && st->application != value))
2036 {
2037 ret = OPUS_BAD_ARG;
2038 break;
2039 }
Jean-Marc Valin69549ac2011-08-18 17:28:28 -04002040 st->application = value;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002041 }
2042 break;
Jean-Marc Valin69549ac2011-08-18 17:28:28 -04002043 case OPUS_GET_APPLICATION_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002044 {
Ralph Giles04cca282011-08-24 00:29:29 -04002045 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002046 if (!value)
2047 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002048 goto bad_arg;
2049 }
Gregory Maxwell220a7d42011-10-01 20:30:16 -04002050 *value = st->application;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002051 }
2052 break;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002053 case OPUS_SET_BITRATE_REQUEST:
2054 {
Ralph Giles04cca282011-08-24 00:29:29 -04002055 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04002056 if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
Jean-Marc Valinba547462011-05-10 17:54:41 -04002057 {
2058 if (value <= 0)
2059 goto bad_arg;
2060 else if (value <= 500)
2061 value = 500;
Jean-Marc Valin69f44c52011-09-07 02:43:23 -04002062 else if (value > (opus_int32)300000*st->channels)
2063 value = (opus_int32)300000*st->channels;
Jean-Marc Valinba547462011-05-10 17:54:41 -04002064 }
2065 st->user_bitrate_bps = value;
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002066 }
2067 break;
2068 case OPUS_GET_BITRATE_REQUEST:
2069 {
Ralph Giles04cca282011-08-24 00:29:29 -04002070 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002071 if (!value)
2072 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002073 goto bad_arg;
2074 }
Gregory Maxwell220a7d42011-10-01 20:30:16 -04002075 *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002076 }
2077 break;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04002078 case OPUS_SET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valin103302b2011-05-19 17:17:44 -04002079 {
Ralph Giles04cca282011-08-24 00:29:29 -04002080 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002081 if((value<1 || value>st->channels) && value != OPUS_AUTO)
2082 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002083 goto bad_arg;
2084 }
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04002085 st->force_channels = value;
Jean-Marc Valin103302b2011-05-19 17:17:44 -04002086 }
2087 break;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04002088 case OPUS_GET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valin103302b2011-05-19 17:17:44 -04002089 {
Ralph Giles04cca282011-08-24 00:29:29 -04002090 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002091 if (!value)
2092 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002093 goto bad_arg;
2094 }
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04002095 *value = st->force_channels;
Jean-Marc Valin103302b2011-05-19 17:17:44 -04002096 }
2097 break;
Jean-Marc Valin9ba17432011-10-24 22:41:18 -04002098 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
2099 {
2100 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002101 if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)
2102 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002103 goto bad_arg;
2104 }
Jean-Marc Valin9ba17432011-10-24 22:41:18 -04002105 st->max_bandwidth = value;
2106 if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
2107 st->silk_mode.maxInternalSampleRate = 8000;
2108 } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
2109 st->silk_mode.maxInternalSampleRate = 12000;
2110 } else {
2111 st->silk_mode.maxInternalSampleRate = 16000;
2112 }
2113 }
2114 break;
2115 case OPUS_GET_MAX_BANDWIDTH_REQUEST:
2116 {
2117 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002118 if (!value)
2119 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002120 goto bad_arg;
2121 }
Jean-Marc Valin9ba17432011-10-24 22:41:18 -04002122 *value = st->max_bandwidth;
2123 }
2124 break;
Jean-Marc Valin05dd36a2010-10-18 12:50:49 -04002125 case OPUS_SET_BANDWIDTH_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002126 {
Ralph Giles04cca282011-08-24 00:29:29 -04002127 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002128 if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO)
2129 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002130 goto bad_arg;
2131 }
Jean-Marc Valin955f94c2011-03-08 22:12:43 -05002132 st->user_bandwidth = value;
Jean-Marc Valin541df0a2011-05-26 00:22:58 -04002133 if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002134 st->silk_mode.maxInternalSampleRate = 8000;
Gregory Maxwell87141892011-10-02 03:19:15 -04002135 } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002136 st->silk_mode.maxInternalSampleRate = 12000;
2137 } else {
2138 st->silk_mode.maxInternalSampleRate = 16000;
2139 }
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002140 }
2141 break;
Jean-Marc Valin05dd36a2010-10-18 12:50:49 -04002142 case OPUS_GET_BANDWIDTH_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002143 {
Ralph Giles04cca282011-08-24 00:29:29 -04002144 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002145 if (!value)
2146 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002147 goto bad_arg;
2148 }
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002149 *value = st->bandwidth;
2150 }
2151 break;
Jean-Marc Valind4827732011-08-19 17:07:16 -04002152 case OPUS_SET_DTX_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002153 {
Ralph Giles04cca282011-08-24 00:29:29 -04002154 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002155 if(value<0 || value>1)
2156 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002157 goto bad_arg;
2158 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002159 st->silk_mode.useDTX = value;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002160 }
2161 break;
Jean-Marc Valind4827732011-08-19 17:07:16 -04002162 case OPUS_GET_DTX_REQUEST:
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002163 {
Ralph Giles04cca282011-08-24 00:29:29 -04002164 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002165 if (!value)
2166 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002167 goto bad_arg;
2168 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002169 *value = st->silk_mode.useDTX;
2170 }
2171 break;
2172 case OPUS_SET_COMPLEXITY_REQUEST:
2173 {
Ralph Giles04cca282011-08-24 00:29:29 -04002174 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002175 if(value<0 || value>10)
2176 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002177 goto bad_arg;
2178 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002179 st->silk_mode.complexity = value;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002180 celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002181 }
2182 break;
2183 case OPUS_GET_COMPLEXITY_REQUEST:
2184 {
Ralph Giles04cca282011-08-24 00:29:29 -04002185 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002186 if (!value)
2187 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002188 goto bad_arg;
2189 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002190 *value = st->silk_mode.complexity;
2191 }
2192 break;
Jean-Marc Valine766d9f2011-08-28 20:27:18 -04002193 case OPUS_SET_INBAND_FEC_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002194 {
Ralph Giles04cca282011-08-24 00:29:29 -04002195 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002196 if(value<0 || value>1)
2197 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002198 goto bad_arg;
2199 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002200 st->silk_mode.useInBandFEC = value;
2201 }
2202 break;
Jean-Marc Valine766d9f2011-08-28 20:27:18 -04002203 case OPUS_GET_INBAND_FEC_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002204 {
Ralph Giles04cca282011-08-24 00:29:29 -04002205 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002206 if (!value)
2207 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002208 goto bad_arg;
2209 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002210 *value = st->silk_mode.useInBandFEC;
2211 }
2212 break;
2213 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
2214 {
Ralph Giles04cca282011-08-24 00:29:29 -04002215 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002216 if (value < 0 || value > 100)
2217 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002218 goto bad_arg;
2219 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002220 st->silk_mode.packetLossPercentage = value;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002221 celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value));
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002222 }
2223 break;
2224 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
2225 {
Ralph Giles04cca282011-08-24 00:29:29 -04002226 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002227 if (!value)
2228 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002229 goto bad_arg;
2230 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002231 *value = st->silk_mode.packetLossPercentage;
2232 }
2233 break;
Jean-Marc Valind7f67002011-08-18 16:55:24 -04002234 case OPUS_SET_VBR_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002235 {
Ralph Giles04cca282011-08-24 00:29:29 -04002236 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002237 if(value<0 || value>1)
2238 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002239 goto bad_arg;
2240 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002241 st->use_vbr = value;
2242 st->silk_mode.useCBR = 1-value;
2243 }
2244 break;
Jean-Marc Valind7f67002011-08-18 16:55:24 -04002245 case OPUS_GET_VBR_REQUEST:
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002246 {
Ralph Giles04cca282011-08-24 00:29:29 -04002247 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002248 if (!value)
2249 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002250 goto bad_arg;
2251 }
Jean-Marc Valin2b68ea92011-02-01 10:35:23 -05002252 *value = st->use_vbr;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002253 }
2254 break;
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05002255 case OPUS_SET_VOICE_RATIO_REQUEST:
2256 {
Ralph Giles04cca282011-08-24 00:29:29 -04002257 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002258 if (value<-1 || value>100)
2259 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002260 goto bad_arg;
2261 }
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05002262 st->voice_ratio = value;
2263 }
2264 break;
2265 case OPUS_GET_VOICE_RATIO_REQUEST:
2266 {
Ralph Giles04cca282011-08-24 00:29:29 -04002267 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002268 if (!value)
2269 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002270 goto bad_arg;
2271 }
Jean-Marc Valinf9bc4602011-03-08 14:57:46 -05002272 *value = st->voice_ratio;
2273 }
2274 break;
Jean-Marc Valinb55b6612011-03-14 15:11:44 -04002275 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
2276 {
Ralph Giles04cca282011-08-24 00:29:29 -04002277 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002278 if(value<0 || value>1)
2279 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002280 goto bad_arg;
2281 }
Jean-Marc Valinb55b6612011-03-14 15:11:44 -04002282 st->vbr_constraint = value;
2283 }
2284 break;
2285 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
2286 {
Ralph Giles04cca282011-08-24 00:29:29 -04002287 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002288 if (!value)
2289 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002290 goto bad_arg;
2291 }
Jean-Marc Valinb55b6612011-03-14 15:11:44 -04002292 *value = st->vbr_constraint;
2293 }
2294 break;
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04002295 case OPUS_SET_SIGNAL_REQUEST:
2296 {
Ralph Giles04cca282011-08-24 00:29:29 -04002297 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002298 if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC)
2299 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002300 goto bad_arg;
2301 }
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04002302 st->signal_type = value;
2303 }
2304 break;
2305 case OPUS_GET_SIGNAL_REQUEST:
2306 {
Ralph Giles04cca282011-08-24 00:29:29 -04002307 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002308 if (!value)
2309 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002310 goto bad_arg;
2311 }
Jean-Marc Valin00cb6f72011-05-26 15:06:30 -04002312 *value = st->signal_type;
2313 }
2314 break;
Jean-Marc Valin9d8b5192011-08-03 12:44:37 -04002315 case OPUS_GET_LOOKAHEAD_REQUEST:
2316 {
Ralph Giles04cca282011-08-24 00:29:29 -04002317 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002318 if (!value)
2319 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002320 goto bad_arg;
2321 }
Jean-Marc Valind186c912011-09-08 15:13:46 -04002322 *value = st->Fs/400;
Jean-Marc Valin68bc8c02011-09-09 11:10:48 -04002323 if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
Koen Vos854fe702011-10-09 20:34:41 -04002324 *value += st->delay_compensation;
Jean-Marc Valin9d8b5192011-08-03 12:44:37 -04002325 }
2326 break;
Timothy B. Terriberrya40689e2012-09-07 06:01:53 -07002327 case OPUS_GET_SAMPLE_RATE_REQUEST:
2328 {
2329 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002330 if (!value)
2331 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002332 goto bad_arg;
2333 }
Timothy B. Terriberrya40689e2012-09-07 06:01:53 -07002334 *value = st->Fs;
2335 }
2336 break;
Jean-Marc Valind4827732011-08-19 17:07:16 -04002337 case OPUS_GET_FINAL_RANGE_REQUEST:
2338 {
2339 opus_uint32 *value = va_arg(ap, opus_uint32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002340 if (!value)
2341 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002342 goto bad_arg;
2343 }
Jean-Marc Valind4827732011-08-19 17:07:16 -04002344 *value = st->rangeFinal;
2345 }
2346 break;
Jean-Marc Valin1cd5d952012-07-11 02:54:47 -04002347 case OPUS_SET_LSB_DEPTH_REQUEST:
2348 {
2349 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002350 if (value<8 || value>24)
2351 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002352 goto bad_arg;
2353 }
Jean-Marc Valin7509fdb2012-12-20 22:48:35 -05002354 st->lsb_depth=value;
Jean-Marc Valin1cd5d952012-07-11 02:54:47 -04002355 }
2356 break;
2357 case OPUS_GET_LSB_DEPTH_REQUEST:
2358 {
2359 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002360 if (!value)
2361 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002362 goto bad_arg;
2363 }
Jean-Marc Valin7509fdb2012-12-20 22:48:35 -05002364 *value = st->lsb_depth;
Jean-Marc Valin1cd5d952012-07-11 02:54:47 -04002365 }
2366 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05002367 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05002368 {
2369 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwelldd7b0da2013-06-29 20:06:07 -07002370 if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS &&
2371 value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS &&
2372 value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS &&
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002373 value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_VARIABLE)
2374 {
2375 goto bad_arg;
Gregory Maxwelldd7b0da2013-06-29 20:06:07 -07002376 }
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05002377 st->variable_duration = value;
Jean-Marc Valin3252bf22013-04-19 03:14:28 -04002378 celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value));
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05002379 }
2380 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05002381 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05002382 {
2383 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002384 if (!value)
2385 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002386 goto bad_arg;
2387 }
Jean-Marc Valin49583ed2012-11-22 13:11:43 -05002388 *value = st->variable_duration;
2389 }
2390 break;
Jean-Marc Valin927488b2011-08-30 20:09:22 -04002391 case OPUS_RESET_STATE:
2392 {
2393 void *silk_enc;
2394 silk_EncControlStruct dummy;
2395 silk_enc = (char*)st+st->silk_enc_offset;
2396
2397 OPUS_CLEAR((char*)&st->OPUS_ENCODER_RESET_START,
Gregory Maxwelld32f9482011-09-04 07:48:20 -04002398 sizeof(OpusEncoder)-
Jean-Marc Valin927488b2011-08-30 20:09:22 -04002399 ((char*)&st->OPUS_ENCODER_RESET_START - (char*)st));
2400
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002401 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
Jean-Marc Valin927488b2011-08-30 20:09:22 -04002402 silk_InitEncoder( silk_enc, &dummy );
2403 st->stream_channels = st->channels;
Koen Vos854fe702011-10-09 20:34:41 -04002404 st->hybrid_stereo_width_Q14 = 1 << 14;
Jean-Marc Valinf68799b2012-07-12 17:36:11 -04002405 st->prev_HB_gain = Q15ONE;
Jean-Marc Valin927488b2011-08-30 20:09:22 -04002406 st->first = 1;
2407 st->mode = MODE_HYBRID;
2408 st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -07002409 st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
Jean-Marc Valin927488b2011-08-30 20:09:22 -04002410 }
2411 break;
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04002412 case OPUS_SET_FORCE_MODE_REQUEST:
2413 {
2414 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002415 if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO)
2416 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002417 goto bad_arg;
2418 }
Jean-Marc Valin07dceb72011-09-08 13:53:20 -04002419 st->user_forced_mode = value;
2420 }
2421 break;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04002422 case OPUS_SET_LFE_REQUEST:
2423 {
2424 opus_int32 value = va_arg(ap, opus_int32);
2425 st->lfe = value;
Gregory Maxwelldd7b0da2013-06-29 20:06:07 -07002426 ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value));
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04002427 }
2428 break;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04002429 case OPUS_SET_ENERGY_MASK_REQUEST:
2430 {
2431 opus_val16 *value = va_arg(ap, opus_val16*);
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -04002432 st->energy_masking = value;
Gregory Maxwelldd7b0da2013-06-29 20:06:07 -07002433 ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04002434 }
2435 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05002436
2437 case CELT_GET_MODE_REQUEST:
2438 {
2439 const CELTMode ** value = va_arg(ap, const CELTMode**);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07002440 if (!value)
2441 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07002442 goto bad_arg;
2443 }
Gregory Maxwelldd7b0da2013-06-29 20:06:07 -07002444 ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05002445 }
2446 break;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002447 default:
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002448 /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002449 ret = OPUS_UNIMPLEMENTED;
Jean-Marc Valin24f36e02010-07-06 14:41:20 -04002450 break;
Jean-Marc Valinc5ea0742010-07-05 11:11:54 -04002451 }
Alfred E. Heggestad3d31d702010-07-27 16:38:04 +02002452 va_end(ap);
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002453 return ret;
Jean-Marc Valind2124cd2011-04-25 13:36:14 -04002454bad_arg:
2455 va_end(ap);
2456 return OPUS_BAD_ARG;
Jean-Marc Valin3e66e912010-06-30 14:16:14 -04002457}
2458
Jean-Marc Valin05dd36a2010-10-18 12:50:49 -04002459void opus_encoder_destroy(OpusEncoder *st)
Jean-Marc Valin3e66e912010-06-30 14:16:14 -04002460{
Jean-Marc Valin07f88402011-08-29 15:08:51 -04002461 opus_free(st);
Jean-Marc Valin3e66e912010-06-30 14:16:14 -04002462}