annotate src/opus-1.3/silk/enc_API.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 7aeed7906520
children
rev   line source
Chris@69 1 /***********************************************************************
Chris@69 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
Chris@69 3 Redistribution and use in source and binary forms, with or without
Chris@69 4 modification, are permitted provided that the following conditions
Chris@69 5 are met:
Chris@69 6 - Redistributions of source code must retain the above copyright notice,
Chris@69 7 this list of conditions and the following disclaimer.
Chris@69 8 - Redistributions in binary form must reproduce the above copyright
Chris@69 9 notice, this list of conditions and the following disclaimer in the
Chris@69 10 documentation and/or other materials provided with the distribution.
Chris@69 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the
Chris@69 12 names of specific contributors, may be used to endorse or promote
Chris@69 13 products derived from this software without specific prior written
Chris@69 14 permission.
Chris@69 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Chris@69 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Chris@69 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Chris@69 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Chris@69 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Chris@69 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Chris@69 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Chris@69 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Chris@69 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Chris@69 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Chris@69 25 POSSIBILITY OF SUCH DAMAGE.
Chris@69 26 ***********************************************************************/
Chris@69 27
Chris@69 28 #ifdef HAVE_CONFIG_H
Chris@69 29 #include "config.h"
Chris@69 30 #endif
Chris@69 31 #include "define.h"
Chris@69 32 #include "API.h"
Chris@69 33 #include "control.h"
Chris@69 34 #include "typedef.h"
Chris@69 35 #include "stack_alloc.h"
Chris@69 36 #include "structs.h"
Chris@69 37 #include "tuning_parameters.h"
Chris@69 38 #ifdef FIXED_POINT
Chris@69 39 #include "main_FIX.h"
Chris@69 40 #else
Chris@69 41 #include "main_FLP.h"
Chris@69 42 #endif
Chris@69 43
Chris@69 44 /***************************************/
Chris@69 45 /* Read control structure from encoder */
Chris@69 46 /***************************************/
Chris@69 47 static opus_int silk_QueryEncoder( /* O Returns error code */
Chris@69 48 const void *encState, /* I State */
Chris@69 49 silk_EncControlStruct *encStatus /* O Encoder Status */
Chris@69 50 );
Chris@69 51
Chris@69 52 /****************************************/
Chris@69 53 /* Encoder functions */
Chris@69 54 /****************************************/
Chris@69 55
Chris@69 56 opus_int silk_Get_Encoder_Size( /* O Returns error code */
Chris@69 57 opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */
Chris@69 58 )
Chris@69 59 {
Chris@69 60 opus_int ret = SILK_NO_ERROR;
Chris@69 61
Chris@69 62 *encSizeBytes = sizeof( silk_encoder );
Chris@69 63
Chris@69 64 return ret;
Chris@69 65 }
Chris@69 66
Chris@69 67 /*************************/
Chris@69 68 /* Init or Reset encoder */
Chris@69 69 /*************************/
Chris@69 70 opus_int silk_InitEncoder( /* O Returns error code */
Chris@69 71 void *encState, /* I/O State */
Chris@69 72 int arch, /* I Run-time architecture */
Chris@69 73 silk_EncControlStruct *encStatus /* O Encoder Status */
Chris@69 74 )
Chris@69 75 {
Chris@69 76 silk_encoder *psEnc;
Chris@69 77 opus_int n, ret = SILK_NO_ERROR;
Chris@69 78
Chris@69 79 psEnc = (silk_encoder *)encState;
Chris@69 80
Chris@69 81 /* Reset encoder */
Chris@69 82 silk_memset( psEnc, 0, sizeof( silk_encoder ) );
Chris@69 83 for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {
Chris@69 84 if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {
Chris@69 85 celt_assert( 0 );
Chris@69 86 }
Chris@69 87 }
Chris@69 88
Chris@69 89 psEnc->nChannelsAPI = 1;
Chris@69 90 psEnc->nChannelsInternal = 1;
Chris@69 91
Chris@69 92 /* Read control structure */
Chris@69 93 if( ret += silk_QueryEncoder( encState, encStatus ) ) {
Chris@69 94 celt_assert( 0 );
Chris@69 95 }
Chris@69 96
Chris@69 97 return ret;
Chris@69 98 }
Chris@69 99
Chris@69 100 /***************************************/
Chris@69 101 /* Read control structure from encoder */
Chris@69 102 /***************************************/
Chris@69 103 static opus_int silk_QueryEncoder( /* O Returns error code */
Chris@69 104 const void *encState, /* I State */
Chris@69 105 silk_EncControlStruct *encStatus /* O Encoder Status */
Chris@69 106 )
Chris@69 107 {
Chris@69 108 opus_int ret = SILK_NO_ERROR;
Chris@69 109 silk_encoder_state_Fxx *state_Fxx;
Chris@69 110 silk_encoder *psEnc = (silk_encoder *)encState;
Chris@69 111
Chris@69 112 state_Fxx = psEnc->state_Fxx;
Chris@69 113
Chris@69 114 encStatus->nChannelsAPI = psEnc->nChannelsAPI;
Chris@69 115 encStatus->nChannelsInternal = psEnc->nChannelsInternal;
Chris@69 116 encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz;
Chris@69 117 encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz;
Chris@69 118 encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz;
Chris@69 119 encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz;
Chris@69 120 encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms;
Chris@69 121 encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps;
Chris@69 122 encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc;
Chris@69 123 encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity;
Chris@69 124 encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC;
Chris@69 125 encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX;
Chris@69 126 encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR;
Chris@69 127 encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
Chris@69 128 encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch;
Chris@69 129 encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0;
Chris@69 130
Chris@69 131 return ret;
Chris@69 132 }
Chris@69 133
Chris@69 134
Chris@69 135 /**************************/
Chris@69 136 /* Encode frame with Silk */
Chris@69 137 /**************************/
Chris@69 138 /* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */
Chris@69 139 /* encControl->payloadSize_ms is set to */
Chris@69 140 opus_int silk_Encode( /* O Returns error code */
Chris@69 141 void *encState, /* I/O State */
Chris@69 142 silk_EncControlStruct *encControl, /* I Control status */
Chris@69 143 const opus_int16 *samplesIn, /* I Speech sample input vector */
Chris@69 144 opus_int nSamplesIn, /* I Number of samples in input vector */
Chris@69 145 ec_enc *psRangeEnc, /* I/O Compressor data structure */
Chris@69 146 opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
Chris@69 147 const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */
Chris@69 148 opus_int activity /* I Decision of Opus voice activity detector */
Chris@69 149 )
Chris@69 150 {
Chris@69 151 opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
Chris@69 152 opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;
Chris@69 153 opus_int nSamplesFromInput = 0, nSamplesFromInputMax;
Chris@69 154 opus_int speech_act_thr_for_switch_Q8;
Chris@69 155 opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
Chris@69 156 silk_encoder *psEnc = ( silk_encoder * )encState;
Chris@69 157 VARDECL( opus_int16, buf );
Chris@69 158 opus_int transition, curr_block, tot_blocks;
Chris@69 159 SAVE_STACK;
Chris@69 160
Chris@69 161 if (encControl->reducedDependency)
Chris@69 162 {
Chris@69 163 psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;
Chris@69 164 psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;
Chris@69 165 }
Chris@69 166 psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
Chris@69 167
Chris@69 168 /* Check values in encoder control structure */
Chris@69 169 if( ( ret = check_control_input( encControl ) ) != 0 ) {
Chris@69 170 celt_assert( 0 );
Chris@69 171 RESTORE_STACK;
Chris@69 172 return ret;
Chris@69 173 }
Chris@69 174
Chris@69 175 encControl->switchReady = 0;
Chris@69 176
Chris@69 177 if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) {
Chris@69 178 /* Mono -> Stereo transition: init state of second channel and stereo state */
Chris@69 179 ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch );
Chris@69 180 silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) );
Chris@69 181 silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) );
Chris@69 182 psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0;
Chris@69 183 psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1;
Chris@69 184 psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0;
Chris@69 185 psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1;
Chris@69 186 psEnc->sStereo.width_prev_Q14 = 0;
Chris@69 187 psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 );
Chris@69 188 if( psEnc->nChannelsAPI == 2 ) {
Chris@69 189 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) );
Chris@69 190 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) );
Chris@69 191 }
Chris@69 192 }
Chris@69 193
Chris@69 194 transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal);
Chris@69 195
Chris@69 196 psEnc->nChannelsAPI = encControl->nChannelsAPI;
Chris@69 197 psEnc->nChannelsInternal = encControl->nChannelsInternal;
Chris@69 198
Chris@69 199 nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate );
Chris@69 200 tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
Chris@69 201 curr_block = 0;
Chris@69 202 if( prefillFlag ) {
Chris@69 203 silk_LP_state save_LP;
Chris@69 204 /* Only accept input length of 10 ms */
Chris@69 205 if( nBlocksOf10ms != 1 ) {
Chris@69 206 celt_assert( 0 );
Chris@69 207 RESTORE_STACK;
Chris@69 208 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
Chris@69 209 }
Chris@69 210 if ( prefillFlag == 2 ) {
Chris@69 211 save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP;
Chris@69 212 /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */
Chris@69 213 save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
Chris@69 214 }
Chris@69 215 /* Reset Encoder */
Chris@69 216 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 217 ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
Chris@69 218 /* Restore the variable LP state. */
Chris@69 219 if ( prefillFlag == 2 ) {
Chris@69 220 psEnc->state_Fxx[ n ].sCmn.sLP = save_LP;
Chris@69 221 }
Chris@69 222 celt_assert( !ret );
Chris@69 223 }
Chris@69 224 tmp_payloadSize_ms = encControl->payloadSize_ms;
Chris@69 225 encControl->payloadSize_ms = 10;
Chris@69 226 tmp_complexity = encControl->complexity;
Chris@69 227 encControl->complexity = 0;
Chris@69 228 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 229 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
Chris@69 230 psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1;
Chris@69 231 }
Chris@69 232 } else {
Chris@69 233 /* Only accept input lengths that are a multiple of 10 ms */
Chris@69 234 if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
Chris@69 235 celt_assert( 0 );
Chris@69 236 RESTORE_STACK;
Chris@69 237 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
Chris@69 238 }
Chris@69 239 /* Make sure no more than one packet can be produced */
Chris@69 240 if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
Chris@69 241 celt_assert( 0 );
Chris@69 242 RESTORE_STACK;
Chris@69 243 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
Chris@69 244 }
Chris@69 245 }
Chris@69 246
Chris@69 247 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 248 /* Force the side channel to the same rate as the mid */
Chris@69 249 opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
Chris@69 250 if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
Chris@69 251 silk_assert( 0 );
Chris@69 252 RESTORE_STACK;
Chris@69 253 return ret;
Chris@69 254 }
Chris@69 255 if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {
Chris@69 256 for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
Chris@69 257 psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0;
Chris@69 258 }
Chris@69 259 }
Chris@69 260 psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
Chris@69 261 }
Chris@69 262 celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
Chris@69 263
Chris@69 264 /* Input buffering/resampling and encoding */
Chris@69 265 nSamplesToBufferMax =
Chris@69 266 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
Chris@69 267 nSamplesFromInputMax =
Chris@69 268 silk_DIV32_16( nSamplesToBufferMax *
Chris@69 269 psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,
Chris@69 270 psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
Chris@69 271 ALLOC( buf, nSamplesFromInputMax, opus_int16 );
Chris@69 272 while( 1 ) {
Chris@69 273 nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
Chris@69 274 nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
Chris@69 275 nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
Chris@69 276 /* Resample and write to buffer */
Chris@69 277 if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
Chris@69 278 opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
Chris@69 279 for( n = 0; n < nSamplesFromInput; n++ ) {
Chris@69 280 buf[ n ] = samplesIn[ 2 * n ];
Chris@69 281 }
Chris@69 282 /* Making sure to start both resamplers from the same state when switching from mono to stereo */
Chris@69 283 if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
Chris@69 284 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
Chris@69 285 }
Chris@69 286
Chris@69 287 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
Chris@69 288 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
Chris@69 289 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
Chris@69 290
Chris@69 291 nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
Chris@69 292 nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
Chris@69 293 for( n = 0; n < nSamplesFromInput; n++ ) {
Chris@69 294 buf[ n ] = samplesIn[ 2 * n + 1 ];
Chris@69 295 }
Chris@69 296 ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
Chris@69 297 &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
Chris@69 298
Chris@69 299 psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
Chris@69 300 } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
Chris@69 301 /* Combine left and right channels before resampling */
Chris@69 302 for( n = 0; n < nSamplesFromInput; n++ ) {
Chris@69 303 sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
Chris@69 304 buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
Chris@69 305 }
Chris@69 306 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
Chris@69 307 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
Chris@69 308 /* On the first mono frame, average the results for the two resampler states */
Chris@69 309 if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) {
Chris@69 310 ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
Chris@69 311 &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
Chris@69 312 for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) {
Chris@69 313 psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] =
Chris@69 314 silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ]
Chris@69 315 + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
Chris@69 316 }
Chris@69 317 }
Chris@69 318 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
Chris@69 319 } else {
Chris@69 320 celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
Chris@69 321 silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
Chris@69 322 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
Chris@69 323 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
Chris@69 324 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
Chris@69 325 }
Chris@69 326
Chris@69 327 samplesIn += nSamplesFromInput * encControl->nChannelsAPI;
Chris@69 328 nSamplesIn -= nSamplesFromInput;
Chris@69 329
Chris@69 330 /* Default */
Chris@69 331 psEnc->allowBandwidthSwitch = 0;
Chris@69 332
Chris@69 333 /* Silk encoder */
Chris@69 334 if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
Chris@69 335 /* Enough data in input buffer, so encode */
Chris@69 336 celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
Chris@69 337 celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
Chris@69 338
Chris@69 339 /* Deal with LBRR data */
Chris@69 340 if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
Chris@69 341 /* Create space at start of payload for VAD and FEC flags */
Chris@69 342 opus_uint8 iCDF[ 2 ] = { 0, 0 };
Chris@69 343 iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
Chris@69 344 ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );
Chris@69 345
Chris@69 346 /* Encode any LBRR data from previous packet */
Chris@69 347 /* Encode LBRR flags */
Chris@69 348 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 349 LBRR_symbol = 0;
Chris@69 350 for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
Chris@69 351 LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i );
Chris@69 352 }
Chris@69 353 psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0;
Chris@69 354 if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) {
Chris@69 355 ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 );
Chris@69 356 }
Chris@69 357 }
Chris@69 358
Chris@69 359 /* Code LBRR indices and excitation signals */
Chris@69 360 for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
Chris@69 361 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 362 if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) {
Chris@69 363 opus_int condCoding;
Chris@69 364
Chris@69 365 if( encControl->nChannelsInternal == 2 && n == 0 ) {
Chris@69 366 silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] );
Chris@69 367 /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */
Chris@69 368 if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) {
Chris@69 369 silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] );
Chris@69 370 }
Chris@69 371 }
Chris@69 372 /* Use conditional coding if previous frame available */
Chris@69 373 if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) {
Chris@69 374 condCoding = CODE_CONDITIONALLY;
Chris@69 375 } else {
Chris@69 376 condCoding = CODE_INDEPENDENTLY;
Chris@69 377 }
Chris@69 378 silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding );
Chris@69 379 silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType,
Chris@69 380 psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length );
Chris@69 381 }
Chris@69 382 }
Chris@69 383 }
Chris@69 384
Chris@69 385 /* Reset LBRR flags */
Chris@69 386 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 387 silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );
Chris@69 388 }
Chris@69 389
Chris@69 390 psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc );
Chris@69 391 }
Chris@69 392
Chris@69 393 silk_HP_variable_cutoff( psEnc->state_Fxx );
Chris@69 394
Chris@69 395 /* Total target bits for packet */
Chris@69 396 nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
Chris@69 397 /* Subtract bits used for LBRR */
Chris@69 398 if( !prefillFlag ) {
Chris@69 399 nBits -= psEnc->nBitsUsedLBRR;
Chris@69 400 }
Chris@69 401 /* Divide by number of uncoded frames left in packet */
Chris@69 402 nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket );
Chris@69 403 /* Convert to bits/second */
Chris@69 404 if( encControl->payloadSize_ms == 10 ) {
Chris@69 405 TargetRate_bps = silk_SMULBB( nBits, 100 );
Chris@69 406 } else {
Chris@69 407 TargetRate_bps = silk_SMULBB( nBits, 50 );
Chris@69 408 }
Chris@69 409 /* Subtract fraction of bits in excess of target in previous frames and packets */
Chris@69 410 TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
Chris@69 411 if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) {
Chris@69 412 /* Compare actual vs target bits so far in this packet */
Chris@69 413 opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
Chris@69 414 TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
Chris@69 415 }
Chris@69 416 /* Never exceed input bitrate */
Chris@69 417 TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );
Chris@69 418
Chris@69 419 /* Convert Left/Right to Mid/Side */
Chris@69 420 if( encControl->nChannelsInternal == 2 ) {
Chris@69 421 silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ],
Chris@69 422 psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ],
Chris@69 423 MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono,
Chris@69 424 psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length );
Chris@69 425 if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
Chris@69 426 /* Reset side channel encoder memory for first frame with side coding */
Chris@69 427 if( psEnc->prev_decode_only_middle == 1 ) {
Chris@69 428 silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
Chris@69 429 silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
Chris@69 430 silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
Chris@69 431 silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
Chris@69 432 psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100;
Chris@69 433 psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100;
Chris@69 434 psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10;
Chris@69 435 psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
Chris@69 436 psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536;
Chris@69 437 psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
Chris@69 438 }
Chris@69 439 silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity );
Chris@69 440 } else {
Chris@69 441 psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
Chris@69 442 }
Chris@69 443 if( !prefillFlag ) {
Chris@69 444 silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
Chris@69 445 if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
Chris@69 446 silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
Chris@69 447 }
Chris@69 448 }
Chris@69 449 } else {
Chris@69 450 /* Buffering */
Chris@69 451 silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
Chris@69 452 silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
Chris@69 453 }
Chris@69 454 silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity );
Chris@69 455
Chris@69 456 /* Encode */
Chris@69 457 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 458 opus_int maxBits, useCBR;
Chris@69 459
Chris@69 460 /* Handling rate constraints */
Chris@69 461 maxBits = encControl->maxBits;
Chris@69 462 if( tot_blocks == 2 && curr_block == 0 ) {
Chris@69 463 maxBits = maxBits * 3 / 5;
Chris@69 464 } else if( tot_blocks == 3 ) {
Chris@69 465 if( curr_block == 0 ) {
Chris@69 466 maxBits = maxBits * 2 / 5;
Chris@69 467 } else if( curr_block == 1 ) {
Chris@69 468 maxBits = maxBits * 3 / 4;
Chris@69 469 }
Chris@69 470 }
Chris@69 471 useCBR = encControl->useCBR && curr_block == tot_blocks - 1;
Chris@69 472
Chris@69 473 if( encControl->nChannelsInternal == 1 ) {
Chris@69 474 channelRate_bps = TargetRate_bps;
Chris@69 475 } else {
Chris@69 476 channelRate_bps = MStargetRates_bps[ n ];
Chris@69 477 if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) {
Chris@69 478 useCBR = 0;
Chris@69 479 /* Give mid up to 1/2 of the max bits for that frame */
Chris@69 480 maxBits -= encControl->maxBits / ( tot_blocks * 2 );
Chris@69 481 }
Chris@69 482 }
Chris@69 483
Chris@69 484 if( channelRate_bps > 0 ) {
Chris@69 485 opus_int condCoding;
Chris@69 486
Chris@69 487 silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps );
Chris@69 488
Chris@69 489 /* Use independent coding if no previous frame available */
Chris@69 490 if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) {
Chris@69 491 condCoding = CODE_INDEPENDENTLY;
Chris@69 492 } else if( n > 0 && psEnc->prev_decode_only_middle ) {
Chris@69 493 /* If we skipped a side frame in this packet, we don't
Chris@69 494 need LTP scaling; the LTP state is well-defined. */
Chris@69 495 condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
Chris@69 496 } else {
Chris@69 497 condCoding = CODE_CONDITIONALLY;
Chris@69 498 }
Chris@69 499 if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) {
Chris@69 500 silk_assert( 0 );
Chris@69 501 }
Chris@69 502 }
Chris@69 503 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
Chris@69 504 psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0;
Chris@69 505 psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++;
Chris@69 506 }
Chris@69 507 psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ];
Chris@69 508
Chris@69 509 /* Insert VAD and FEC flags at beginning of bitstream */
Chris@69 510 if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) {
Chris@69 511 flags = 0;
Chris@69 512 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 513 for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
Chris@69 514 flags = silk_LSHIFT( flags, 1 );
Chris@69 515 flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ];
Chris@69 516 }
Chris@69 517 flags = silk_LSHIFT( flags, 1 );
Chris@69 518 flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag;
Chris@69 519 }
Chris@69 520 if( !prefillFlag ) {
Chris@69 521 ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
Chris@69 522 }
Chris@69 523
Chris@69 524 /* Return zero bytes if all channels DTXed */
Chris@69 525 if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) {
Chris@69 526 *nBytesOut = 0;
Chris@69 527 }
Chris@69 528
Chris@69 529 psEnc->nBitsExceeded += *nBytesOut * 8;
Chris@69 530 psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
Chris@69 531 psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 );
Chris@69 532
Chris@69 533 /* Update flag indicating if bandwidth switching is allowed */
Chris@69 534 speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),
Chris@69 535 SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );
Chris@69 536 if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {
Chris@69 537 psEnc->allowBandwidthSwitch = 1;
Chris@69 538 psEnc->timeSinceSwitchAllowed_ms = 0;
Chris@69 539 } else {
Chris@69 540 psEnc->allowBandwidthSwitch = 0;
Chris@69 541 psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;
Chris@69 542 }
Chris@69 543 }
Chris@69 544
Chris@69 545 if( nSamplesIn == 0 ) {
Chris@69 546 break;
Chris@69 547 }
Chris@69 548 } else {
Chris@69 549 break;
Chris@69 550 }
Chris@69 551 curr_block++;
Chris@69 552 }
Chris@69 553
Chris@69 554 psEnc->nPrevChannelsInternal = encControl->nChannelsInternal;
Chris@69 555
Chris@69 556 encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;
Chris@69 557 encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0;
Chris@69 558 encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
Chris@69 559 encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14;
Chris@69 560 if( prefillFlag ) {
Chris@69 561 encControl->payloadSize_ms = tmp_payloadSize_ms;
Chris@69 562 encControl->complexity = tmp_complexity;
Chris@69 563 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
Chris@69 564 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
Chris@69 565 psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0;
Chris@69 566 }
Chris@69 567 }
Chris@69 568
Chris@69 569 encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType;
Chris@69 570 encControl->offset = silk_Quantization_Offsets_Q10
Chris@69 571 [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ]
Chris@69 572 [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ];
Chris@69 573 RESTORE_STACK;
Chris@69 574 return ret;
Chris@69 575 }
Chris@69 576