15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*********************************************************************** 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Copyright (c) 2006-2011, Skype Limited. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Redistribution and use in source and binary forms, with or without 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)modification, are permitted provided that the following conditions 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)are met: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- Redistributions of source code must retain the above copyright notice, 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)this list of conditions and the following disclaimer. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- Redistributions in binary form must reproduce the above copyright 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)notice, this list of conditions and the following disclaimer in the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)documentation and/or other materials provided with the distribution. 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)- Neither the name of Internet Society, IETF or IETF Trust, nor the 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinames of specific contributors, may be used to endorse or promote 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)products derived from this software without specific prior written 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)permission. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochPOSSIBILITY OF SUCH DAMAGE. 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch***********************************************************************/ 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h" 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "main_FLP.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tuning_parameters.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* coefficient in an array of coefficients, for monic filters. */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static OPUS_INLINE silk_float warped_gain( 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const silk_float *coefs, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float lambda, 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) opus_int order 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opus_int i; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float gain; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lambda = -lambda; 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gain = coefs[ order - 1 ]; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for( i = order - 2; i >= 0; i-- ) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gain = lambda * gain + coefs[ i ]; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) ); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static OPUS_INLINE void warped_true2monic_coefs( 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float *coefs_syn, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float *coefs_ana, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float lambda, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silk_float limit, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opus_int order 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opus_int i, iter, ind = 0; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float tmp, maxabs, chirp, gain_syn, gain_ana; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Convert to monic coefficients */ 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for( i = order - 1; i > 0; i-- ) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( i = 0; i < order; i++ ) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_syn[ i ] *= gain_syn; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_ana[ i ] *= gain_ana; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Limit */ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( iter = 0; iter < 10; iter++ ) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find maximum absolute value */ 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxabs = -1.0f; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( i = 0; i < order; i++ ) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) ); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( tmp > maxabs ) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxabs = tmp; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ind = i; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( maxabs <= limit ) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Coefficients are within range - done */ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Convert back to true warped coefficients */ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( i = 1; i < order; i++ ) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ]; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ]; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gain_syn = 1.0f / gain_syn; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gain_ana = 1.0f / gain_ana; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( i = 0; i < order; i++ ) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_syn[ i ] *= gain_syn; 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch coefs_ana[ i ] *= gain_ana; 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Apply bandwidth expansion */ 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch silk_bwexpander_FLP( coefs_syn, order, chirp ); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_bwexpander_FLP( coefs_ana, order, chirp ); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Convert to monic warped coefficients */ 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for( i = order - 1; i > 0; i-- ) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( i = 0; i < order; i++ ) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_syn[ i ] *= gain_syn; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coefs_ana[ i ] *= gain_ana; 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_assert( 0 ); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/* Compute noise shaping coefficients and initial gain values */ 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void silk_noise_shape_analysis_FLP( 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const silk_float *pitch_res, /* I LPC residual from pitch analysis */ 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const silk_float *x /* I Input signal [frame_length + la_shape] */ 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch silk_shape_state_FLP *psShapeSt = &psEnc->sShape; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opus_int k, nSamples; 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) silk_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation; 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) silk_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float x_windowed[ SHAPE_LPC_WIN_MAX ]; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const silk_float *x_ptr, *pitch_res_ptr; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Point to start of first LPC analysis block */ 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_ptr = x - psEnc->sCmn.la_shape; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /****************/ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* GAIN CONTROL */ 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /****************/ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Input quality is the average of the quality in the lowest two VAD bands */ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f ); 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Coding quality level, between 0.0 and 1.0 */ 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) ); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psEnc->sCmn.useCBR == 0 ) { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Reduce coding SNR during low speech activity */ 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b; 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Reduce gains for periodic signals */ 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr; 1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality ); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /*************************/ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* SPARSENESS PROCESSING */ 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) /*************************/ 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set quantizer offset */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initially set to 0; may be overruled in process_gains(..) */ 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) psEnc->sCmn.indices.quantOffsetType = 0; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psEncCtrl->sparseness = 0.0f; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nSamples = 2 * psEnc->sCmn.fs_kHz; 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) energy_variation = 0.0f; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_energy_prev = 0.0f; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pitch_res_ptr = pitch_res; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples ); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_energy = silk_log2( nrg ); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( k > 0 ) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) energy_variation += silk_abs_float( log_energy - log_energy_prev ); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_energy_prev = log_energy; 193 pitch_res_ptr += nSamples; 194 } 195 psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) ); 196 197 /* Set quantization offset depending on sparseness measure */ 198 if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) { 199 psEnc->sCmn.indices.quantOffsetType = 0; 200 } else { 201 psEnc->sCmn.indices.quantOffsetType = 1; 202 } 203 204 /* Increase coding SNR for sparse signals */ 205 SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f ); 206 } 207 208 /*******************************/ 209 /* Control bandwidth expansion */ 210 /*******************************/ 211 /* More BWE for signals with high prediction gain */ 212 strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */ 213 BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength ); 214 delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality ); 215 BWExp1 -= delta; 216 BWExp2 += delta; 217 /* BWExp1 will be applied after BWExp2, so make it relative */ 218 BWExp1 /= BWExp2; 219 220 if( psEnc->sCmn.warping_Q16 > 0 ) { 221 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ 222 warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality; 223 } else { 224 warping = 0.0f; 225 } 226 227 /********************************************/ 228 /* Compute noise shaping AR coefs and gains */ 229 /********************************************/ 230 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 231 /* Apply window: sine slope followed by flat part followed by cosine slope */ 232 opus_int shift, slope_part, flat_part; 233 flat_part = psEnc->sCmn.fs_kHz * 3; 234 slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2; 235 236 silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part ); 237 shift = slope_part; 238 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) ); 239 shift += flat_part; 240 silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part ); 241 242 /* Update pointer: next LPC analysis block */ 243 x_ptr += psEnc->sCmn.subfr_length; 244 245 if( psEnc->sCmn.warping_Q16 > 0 ) { 246 /* Calculate warped auto correlation */ 247 silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping, 248 psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); 249 } else { 250 /* Calculate regular auto correlation */ 251 silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); 252 } 253 254 /* Add white noise, as a fraction of energy */ 255 auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION; 256 257 /* Convert correlations to prediction coefficients, and compute residual energy */ 258 nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder ); 259 psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg ); 260 261 if( psEnc->sCmn.warping_Q16 > 0 ) { 262 /* Adjust gain for warping */ 263 psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder ); 264 } 265 266 /* Bandwidth expansion for synthesis filter shaping */ 267 silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 ); 268 269 /* Compute noise shaping filter coefficients */ 270 silk_memcpy( 271 &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], 272 &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], 273 psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) ); 274 275 /* Bandwidth expansion for analysis filter shaping */ 276 silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 ); 277 278 /* Ratio of prediction gains, in energy domain */ 279 pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); 280 nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); 281 psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ); 282 283 /* Convert to monic warped prediction coefficients and limit absolute values */ 284 warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], 285 warping, 3.999f, psEnc->sCmn.shapingLPCOrder ); 286 } 287 288 /*****************/ 289 /* Gain tweaking */ 290 /*****************/ 291 /* Increase gains during low speech activity */ 292 gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB ); 293 gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB ); 294 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 295 psEncCtrl->Gains[ k ] *= gain_mult; 296 psEncCtrl->Gains[ k ] += gain_add; 297 } 298 299 gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT; 300 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 301 psEncCtrl->GainsPre[ k ] *= gain_mult; 302 } 303 304 /************************************************/ 305 /* Control low-frequency shaping and noise tilt */ 306 /************************************************/ 307 /* Less low frequency shaping for noisy inputs */ 308 strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) ); 309 strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); 310 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 311 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ 312 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ 313 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 314 b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ]; 315 psEncCtrl->LF_MA_shp[ k ] = -1.0f + b; 316 psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength; 317 } 318 Tilt = - HP_NOISE_COEF - 319 (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); 320 } else { 321 b = 1.3f / psEnc->sCmn.fs_kHz; 322 psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b; 323 psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; 324 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { 325 psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ]; 326 psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ]; 327 } 328 Tilt = -HP_NOISE_COEF; 329 } 330 331 /****************************/ 332 /* HARMONIC SHAPING CONTROL */ 333 /****************************/ 334 /* Control boosting of harmonic frequencies */ 335 HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr; 336 337 /* More harmonic boost for noisy input signals */ 338 HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality ); 339 340 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 341 /* Harmonic noise shaping */ 342 HarmShapeGain = HARMONIC_SHAPING; 343 344 /* More harmonic noise shaping for high bitrates or noisy input */ 345 HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * 346 ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality ); 347 348 /* Less harmonic noise shaping for less periodic signals */ 349 HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr ); 350 } else { 351 HarmShapeGain = 0.0f; 352 } 353 354 /*************************/ 355 /* Smooth over subframes */ 356 /*************************/ 357 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 358 psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth ); 359 psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth; 360 psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth ); 361 psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth; 362 psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth ); 363 psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth; 364 } 365} 366