media/libopus/silk/control_codec.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /***********************************************************************
michael@0 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
michael@0 3 Redistribution and use in source and binary forms, with or without
michael@0 4 modification, are permitted provided that the following conditions
michael@0 5 are met:
michael@0 6 - Redistributions of source code must retain the above copyright notice,
michael@0 7 this list of conditions and the following disclaimer.
michael@0 8 - Redistributions in binary form must reproduce the above copyright
michael@0 9 notice, this list of conditions and the following disclaimer in the
michael@0 10 documentation and/or other materials provided with the distribution.
michael@0 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the
michael@0 12 names of specific contributors, may be used to endorse or promote
michael@0 13 products derived from this software without specific prior written
michael@0 14 permission.
michael@0 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
michael@0 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
michael@0 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
michael@0 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
michael@0 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
michael@0 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
michael@0 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
michael@0 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
michael@0 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
michael@0 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
michael@0 25 POSSIBILITY OF SUCH DAMAGE.
michael@0 26 ***********************************************************************/
michael@0 27
michael@0 28 #ifdef HAVE_CONFIG_H
michael@0 29 #include "config.h"
michael@0 30 #endif
michael@0 31 #ifdef FIXED_POINT
michael@0 32 #include "main_FIX.h"
michael@0 33 #define silk_encoder_state_Fxx silk_encoder_state_FIX
michael@0 34 #else
michael@0 35 #include "main_FLP.h"
michael@0 36 #define silk_encoder_state_Fxx silk_encoder_state_FLP
michael@0 37 #endif
michael@0 38 #include "stack_alloc.h"
michael@0 39 #include "tuning_parameters.h"
michael@0 40 #include "pitch_est_defines.h"
michael@0 41
michael@0 42 static opus_int silk_setup_resamplers(
michael@0 43 silk_encoder_state_Fxx *psEnc, /* I/O */
michael@0 44 opus_int fs_kHz /* I */
michael@0 45 );
michael@0 46
michael@0 47 static opus_int silk_setup_fs(
michael@0 48 silk_encoder_state_Fxx *psEnc, /* I/O */
michael@0 49 opus_int fs_kHz, /* I */
michael@0 50 opus_int PacketSize_ms /* I */
michael@0 51 );
michael@0 52
michael@0 53 static opus_int silk_setup_complexity(
michael@0 54 silk_encoder_state *psEncC, /* I/O */
michael@0 55 opus_int Complexity /* I */
michael@0 56 );
michael@0 57
michael@0 58 static OPUS_INLINE opus_int silk_setup_LBRR(
michael@0 59 silk_encoder_state *psEncC, /* I/O */
michael@0 60 const opus_int32 TargetRate_bps /* I */
michael@0 61 );
michael@0 62
michael@0 63
michael@0 64 /* Control encoder */
michael@0 65 opus_int silk_control_encoder(
michael@0 66 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
michael@0 67 silk_EncControlStruct *encControl, /* I Control structure */
michael@0 68 const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */
michael@0 69 const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
michael@0 70 const opus_int channelNb, /* I Channel number */
michael@0 71 const opus_int force_fs_kHz
michael@0 72 )
michael@0 73 {
michael@0 74 opus_int fs_kHz, ret = 0;
michael@0 75
michael@0 76 psEnc->sCmn.useDTX = encControl->useDTX;
michael@0 77 psEnc->sCmn.useCBR = encControl->useCBR;
michael@0 78 psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate;
michael@0 79 psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate;
michael@0 80 psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate;
michael@0 81 psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate;
michael@0 82 psEnc->sCmn.useInBandFEC = encControl->useInBandFEC;
michael@0 83 psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI;
michael@0 84 psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal;
michael@0 85 psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch;
michael@0 86 psEnc->sCmn.channelNb = channelNb;
michael@0 87
michael@0 88 if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) {
michael@0 89 if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
michael@0 90 /* Change in API sampling rate in the middle of encoding a packet */
michael@0 91 ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz );
michael@0 92 }
michael@0 93 return ret;
michael@0 94 }
michael@0 95
michael@0 96 /* Beyond this point we know that there are no previously coded frames in the payload buffer */
michael@0 97
michael@0 98 /********************************************/
michael@0 99 /* Determine internal sampling rate */
michael@0 100 /********************************************/
michael@0 101 fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl );
michael@0 102 if( force_fs_kHz ) {
michael@0 103 fs_kHz = force_fs_kHz;
michael@0 104 }
michael@0 105 /********************************************/
michael@0 106 /* Prepare resampler and buffered data */
michael@0 107 /********************************************/
michael@0 108 ret += silk_setup_resamplers( psEnc, fs_kHz );
michael@0 109
michael@0 110 /********************************************/
michael@0 111 /* Set internal sampling frequency */
michael@0 112 /********************************************/
michael@0 113 ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms );
michael@0 114
michael@0 115 /********************************************/
michael@0 116 /* Set encoding complexity */
michael@0 117 /********************************************/
michael@0 118 ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity );
michael@0 119
michael@0 120 /********************************************/
michael@0 121 /* Set packet loss rate measured by farend */
michael@0 122 /********************************************/
michael@0 123 psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage;
michael@0 124
michael@0 125 /********************************************/
michael@0 126 /* Set LBRR usage */
michael@0 127 /********************************************/
michael@0 128 ret += silk_setup_LBRR( &psEnc->sCmn, TargetRate_bps );
michael@0 129
michael@0 130 psEnc->sCmn.controlled_since_last_payload = 1;
michael@0 131
michael@0 132 return ret;
michael@0 133 }
michael@0 134
michael@0 135 static opus_int silk_setup_resamplers(
michael@0 136 silk_encoder_state_Fxx *psEnc, /* I/O */
michael@0 137 opus_int fs_kHz /* I */
michael@0 138 )
michael@0 139 {
michael@0 140 opus_int ret = SILK_NO_ERROR;
michael@0 141 SAVE_STACK;
michael@0 142
michael@0 143 if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz )
michael@0 144 {
michael@0 145 if( psEnc->sCmn.fs_kHz == 0 ) {
michael@0 146 /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
michael@0 147 ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 );
michael@0 148 } else {
michael@0 149 VARDECL( opus_int16, x_buf_API_fs_Hz );
michael@0 150 VARDECL( silk_resampler_state_struct, temp_resampler_state );
michael@0 151 #ifdef FIXED_POINT
michael@0 152 opus_int16 *x_bufFIX = psEnc->x_buf;
michael@0 153 #else
michael@0 154 VARDECL( opus_int16, x_bufFIX );
michael@0 155 opus_int32 new_buf_samples;
michael@0 156 #endif
michael@0 157 opus_int32 api_buf_samples;
michael@0 158 opus_int32 old_buf_samples;
michael@0 159 opus_int32 buf_length_ms;
michael@0 160
michael@0 161 buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS;
michael@0 162 old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz;
michael@0 163
michael@0 164 #ifndef FIXED_POINT
michael@0 165 new_buf_samples = buf_length_ms * fs_kHz;
michael@0 166 ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ),
michael@0 167 opus_int16 );
michael@0 168 silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples );
michael@0 169 #endif
michael@0 170
michael@0 171 /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
michael@0 172 ALLOC( temp_resampler_state, 1, silk_resampler_state_struct );
michael@0 173 ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );
michael@0 174
michael@0 175 /* Calculate number of samples to temporarily upsample */
michael@0 176 api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 );
michael@0 177
michael@0 178 /* Temporary resampling of x_buf data to API_fs_Hz */
michael@0 179 ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 );
michael@0 180 ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples );
michael@0 181
michael@0 182 /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
michael@0 183 ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 );
michael@0 184
michael@0 185 /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */
michael@0 186 ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples );
michael@0 187
michael@0 188 #ifndef FIXED_POINT
michael@0 189 silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples);
michael@0 190 #endif
michael@0 191 }
michael@0 192 }
michael@0 193
michael@0 194 psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
michael@0 195
michael@0 196 RESTORE_STACK;
michael@0 197 return ret;
michael@0 198 }
michael@0 199
michael@0 200 static opus_int silk_setup_fs(
michael@0 201 silk_encoder_state_Fxx *psEnc, /* I/O */
michael@0 202 opus_int fs_kHz, /* I */
michael@0 203 opus_int PacketSize_ms /* I */
michael@0 204 )
michael@0 205 {
michael@0 206 opus_int ret = SILK_NO_ERROR;
michael@0 207
michael@0 208 /* Set packet size */
michael@0 209 if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
michael@0 210 if( ( PacketSize_ms != 10 ) &&
michael@0 211 ( PacketSize_ms != 20 ) &&
michael@0 212 ( PacketSize_ms != 40 ) &&
michael@0 213 ( PacketSize_ms != 60 ) ) {
michael@0 214 ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
michael@0 215 }
michael@0 216 if( PacketSize_ms <= 10 ) {
michael@0 217 psEnc->sCmn.nFramesPerPacket = 1;
michael@0 218 psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1;
michael@0 219 psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz );
michael@0 220 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
michael@0 221 if( psEnc->sCmn.fs_kHz == 8 ) {
michael@0 222 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
michael@0 223 } else {
michael@0 224 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
michael@0 225 }
michael@0 226 } else {
michael@0 227 psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS );
michael@0 228 psEnc->sCmn.nb_subfr = MAX_NB_SUBFR;
michael@0 229 psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz );
michael@0 230 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
michael@0 231 if( psEnc->sCmn.fs_kHz == 8 ) {
michael@0 232 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
michael@0 233 } else {
michael@0 234 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
michael@0 235 }
michael@0 236 }
michael@0 237 psEnc->sCmn.PacketSize_ms = PacketSize_ms;
michael@0 238 psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
michael@0 239 }
michael@0 240
michael@0 241 /* Set internal sampling frequency */
michael@0 242 silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
michael@0 243 silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
michael@0 244 if( psEnc->sCmn.fs_kHz != fs_kHz ) {
michael@0 245 /* reset part of the state */
michael@0 246 silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) );
michael@0 247 silk_memset( &psEnc->sPrefilt, 0, sizeof( psEnc->sPrefilt ) );
michael@0 248 silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) );
michael@0 249 silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
michael@0 250 silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );
michael@0 251 psEnc->sCmn.inputBufIx = 0;
michael@0 252 psEnc->sCmn.nFramesEncoded = 0;
michael@0 253 psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
michael@0 254
michael@0 255 /* Initialize non-zero parameters */
michael@0 256 psEnc->sCmn.prevLag = 100;
michael@0 257 psEnc->sCmn.first_frame_after_reset = 1;
michael@0 258 psEnc->sPrefilt.lagPrev = 100;
michael@0 259 psEnc->sShape.LastGainIndex = 10;
michael@0 260 psEnc->sCmn.sNSQ.lagPrev = 100;
michael@0 261 psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536;
michael@0 262 psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
michael@0 263
michael@0 264 psEnc->sCmn.fs_kHz = fs_kHz;
michael@0 265 if( psEnc->sCmn.fs_kHz == 8 ) {
michael@0 266 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
michael@0 267 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
michael@0 268 } else {
michael@0 269 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
michael@0 270 }
michael@0 271 } else {
michael@0 272 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
michael@0 273 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
michael@0 274 } else {
michael@0 275 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
michael@0 276 }
michael@0 277 }
michael@0 278 if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) {
michael@0 279 psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
michael@0 280 psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB;
michael@0 281 } else {
michael@0 282 psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
michael@0 283 psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB;
michael@0 284 }
michael@0 285 psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz;
michael@0 286 psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
michael@0 287 psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz );
michael@0 288 psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz );
michael@0 289 psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz );
michael@0 290 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
michael@0 291 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
michael@0 292 } else {
michael@0 293 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
michael@0 294 }
michael@0 295 if( psEnc->sCmn.fs_kHz == 16 ) {
michael@0 296 psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_WB, 9 );
michael@0 297 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;
michael@0 298 } else if( psEnc->sCmn.fs_kHz == 12 ) {
michael@0 299 psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_MB, 9 );
michael@0 300 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;
michael@0 301 } else {
michael@0 302 psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_NB, 9 );
michael@0 303 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
michael@0 304 }
michael@0 305 }
michael@0 306
michael@0 307 /* Check that settings are valid */
michael@0 308 silk_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
michael@0 309
michael@0 310 return ret;
michael@0 311 }
michael@0 312
michael@0 313 static opus_int silk_setup_complexity(
michael@0 314 silk_encoder_state *psEncC, /* I/O */
michael@0 315 opus_int Complexity /* I */
michael@0 316 )
michael@0 317 {
michael@0 318 opus_int ret = 0;
michael@0 319
michael@0 320 /* Set encoding complexity */
michael@0 321 silk_assert( Complexity >= 0 && Complexity <= 10 );
michael@0 322 if( Complexity < 2 ) {
michael@0 323 psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
michael@0 324 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
michael@0 325 psEncC->pitchEstimationLPCOrder = 6;
michael@0 326 psEncC->shapingLPCOrder = 8;
michael@0 327 psEncC->la_shape = 3 * psEncC->fs_kHz;
michael@0 328 psEncC->nStatesDelayedDecision = 1;
michael@0 329 psEncC->useInterpolatedNLSFs = 0;
michael@0 330 psEncC->LTPQuantLowComplexity = 1;
michael@0 331 psEncC->NLSF_MSVQ_Survivors = 2;
michael@0 332 psEncC->warping_Q16 = 0;
michael@0 333 } else if( Complexity < 4 ) {
michael@0 334 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
michael@0 335 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
michael@0 336 psEncC->pitchEstimationLPCOrder = 8;
michael@0 337 psEncC->shapingLPCOrder = 10;
michael@0 338 psEncC->la_shape = 5 * psEncC->fs_kHz;
michael@0 339 psEncC->nStatesDelayedDecision = 1;
michael@0 340 psEncC->useInterpolatedNLSFs = 0;
michael@0 341 psEncC->LTPQuantLowComplexity = 0;
michael@0 342 psEncC->NLSF_MSVQ_Survivors = 4;
michael@0 343 psEncC->warping_Q16 = 0;
michael@0 344 } else if( Complexity < 6 ) {
michael@0 345 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
michael@0 346 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 );
michael@0 347 psEncC->pitchEstimationLPCOrder = 10;
michael@0 348 psEncC->shapingLPCOrder = 12;
michael@0 349 psEncC->la_shape = 5 * psEncC->fs_kHz;
michael@0 350 psEncC->nStatesDelayedDecision = 2;
michael@0 351 psEncC->useInterpolatedNLSFs = 1;
michael@0 352 psEncC->LTPQuantLowComplexity = 0;
michael@0 353 psEncC->NLSF_MSVQ_Survivors = 8;
michael@0 354 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
michael@0 355 } else if( Complexity < 8 ) {
michael@0 356 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
michael@0 357 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 );
michael@0 358 psEncC->pitchEstimationLPCOrder = 12;
michael@0 359 psEncC->shapingLPCOrder = 14;
michael@0 360 psEncC->la_shape = 5 * psEncC->fs_kHz;
michael@0 361 psEncC->nStatesDelayedDecision = 3;
michael@0 362 psEncC->useInterpolatedNLSFs = 1;
michael@0 363 psEncC->LTPQuantLowComplexity = 0;
michael@0 364 psEncC->NLSF_MSVQ_Survivors = 16;
michael@0 365 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
michael@0 366 } else {
michael@0 367 psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX;
michael@0 368 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 );
michael@0 369 psEncC->pitchEstimationLPCOrder = 16;
michael@0 370 psEncC->shapingLPCOrder = 16;
michael@0 371 psEncC->la_shape = 5 * psEncC->fs_kHz;
michael@0 372 psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
michael@0 373 psEncC->useInterpolatedNLSFs = 1;
michael@0 374 psEncC->LTPQuantLowComplexity = 0;
michael@0 375 psEncC->NLSF_MSVQ_Survivors = 32;
michael@0 376 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
michael@0 377 }
michael@0 378
michael@0 379 /* Do not allow higher pitch estimation LPC order than predict LPC order */
michael@0 380 psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder );
michael@0 381 psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;
michael@0 382 psEncC->Complexity = Complexity;
michael@0 383
michael@0 384 silk_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
michael@0 385 silk_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER );
michael@0 386 silk_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES );
michael@0 387 silk_assert( psEncC->warping_Q16 <= 32767 );
michael@0 388 silk_assert( psEncC->la_shape <= LA_SHAPE_MAX );
michael@0 389 silk_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX );
michael@0 390 silk_assert( psEncC->NLSF_MSVQ_Survivors <= NLSF_VQ_MAX_SURVIVORS );
michael@0 391
michael@0 392 return ret;
michael@0 393 }
michael@0 394
michael@0 395 static OPUS_INLINE opus_int silk_setup_LBRR(
michael@0 396 silk_encoder_state *psEncC, /* I/O */
michael@0 397 const opus_int32 TargetRate_bps /* I */
michael@0 398 )
michael@0 399 {
michael@0 400 opus_int ret = SILK_NO_ERROR;
michael@0 401 opus_int32 LBRR_rate_thres_bps;
michael@0 402
michael@0 403 psEncC->LBRR_enabled = 0;
michael@0 404 if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) {
michael@0 405 if( psEncC->fs_kHz == 8 ) {
michael@0 406 LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS;
michael@0 407 } else if( psEncC->fs_kHz == 12 ) {
michael@0 408 LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS;
michael@0 409 } else {
michael@0 410 LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS;
michael@0 411 }
michael@0 412 LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );
michael@0 413
michael@0 414 if( TargetRate_bps > LBRR_rate_thres_bps ) {
michael@0 415 /* Set gain increase for coding LBRR excitation */
michael@0 416 psEncC->LBRR_enabled = 1;
michael@0 417 psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
michael@0 418 }
michael@0 419 }
michael@0 420
michael@0 421 return ret;
michael@0 422 }

mercurial