1 /*********************************************************************** 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved. 3 Redistribution and use in source and binary forms, with or without 4 modification, are permitted provided that the following conditions 5 are met: 6 - Redistributions of source code must retain the above copyright notice, 7 this list of conditions and the following disclaimer. 8 - Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the 12 names of specific contributors, may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 POSSIBILITY OF SUCH DAMAGE. 26 ***********************************************************************/ 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #include "main_FLP.h" 33 #include "tuning_parameters.h" 34 35 /* 36 * Prefilter for finding Quantizer input signal 37 */ 38 static OPUS_INLINE void silk_prefilt_FLP( 39 silk_prefilter_state_FLP *P, /* I/O state */ 40 silk_float st_res[], /* I */ 41 silk_float xw[], /* O */ 42 silk_float *HarmShapeFIR, /* I */ 43 silk_float Tilt, /* I */ 44 silk_float LF_MA_shp, /* I */ 45 silk_float LF_AR_shp, /* I */ 46 opus_int lag, /* I */ 47 opus_int length /* I */ 48 ); 49 50 static void silk_warped_LPC_analysis_filter_FLP( 51 silk_float state[], /* I/O State [order + 1] */ 52 silk_float res[], /* O Residual signal [length] */ 53 const silk_float coef[], /* I Coefficients [order] */ 54 const silk_float input[], /* I Input signal [length] */ 55 const silk_float lambda, /* I Warping factor */ 56 const opus_int length, /* I Length of input signal */ 57 const opus_int order /* I Filter order (even) */ 58 ) 59 { 60 opus_int n, i; 61 silk_float acc, tmp1, tmp2; 62 63 /* Order must be even */ 64 silk_assert( ( order & 1 ) == 0 ); 65 66 for( n = 0; n < length; n++ ) { 67 /* Output of lowpass section */ 68 tmp2 = state[ 0 ] + lambda * state[ 1 ]; 69 state[ 0 ] = input[ n ]; 70 /* Output of allpass section */ 71 tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 ); 72 state[ 1 ] = tmp2; 73 acc = coef[ 0 ] * tmp2; 74 /* Loop over allpass sections */ 75 for( i = 2; i < order; i += 2 ) { 76 /* Output of allpass section */ 77 tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 ); 78 state[ i ] = tmp1; 79 acc += coef[ i - 1 ] * tmp1; 80 /* Output of allpass section */ 81 tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 ); 82 state[ i + 1 ] = tmp2; 83 acc += coef[ i ] * tmp2; 84 } 85 state[ order ] = tmp1; 86 acc += coef[ order - 1 ] * tmp1; 87 res[ n ] = input[ n ] - acc; 88 } 89 } 90 91 /* 92 * silk_prefilter. Main prefilter function 93 */ 94 void silk_prefilter_FLP( 95 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ 96 const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */ 97 silk_float xw[], /* O Weighted signal */ 98 const silk_float x[] /* I Speech signal */ 99 ) 100 { 101 silk_prefilter_state_FLP *P = &psEnc->sPrefilt; 102 opus_int j, k, lag; 103 silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp; 104 silk_float B[ 2 ]; 105 const silk_float *AR1_shp; 106 const silk_float *px; 107 silk_float *pxw; 108 silk_float HarmShapeFIR[ 3 ]; 109 silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; 110 111 /* Set up pointers */ 112 px = x; 113 pxw = xw; 114 lag = P->lagPrev; 115 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 116 /* Update Variables that change per sub frame */ 117 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 118 lag = psEncCtrl->pitchL[ k ]; 119 } 120 121 /* Noise shape parameters */ 122 HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] ); 123 HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain; 124 HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain; 125 HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain; 126 Tilt = psEncCtrl->Tilt[ k ]; 127 LF_MA_shp = psEncCtrl->LF_MA_shp[ k ]; 128 LF_AR_shp = psEncCtrl->LF_AR_shp[ k ]; 129 AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ]; 130 131 /* Short term FIR filtering */ 132 silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px, 133 (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); 134 135 /* Reduce (mainly) low frequencies during harmonic emphasis */ 136 B[ 0 ] = psEncCtrl->GainsPre[ k ]; 137 B[ 1 ] = -psEncCtrl->GainsPre[ k ] * 138 ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT ); 139 pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP; 140 for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { 141 pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ]; 142 } 143 P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; 144 145 silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length ); 146 147 px += psEnc->sCmn.subfr_length; 148 pxw += psEnc->sCmn.subfr_length; 149 } 150 P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; 151 } 152 153 /* 154 * Prefilter for finding Quantizer input signal 155 */ 156 static OPUS_INLINE void silk_prefilt_FLP( 157 silk_prefilter_state_FLP *P, /* I/O state */ 158 silk_float st_res[], /* I */ 159 silk_float xw[], /* O */ 160 silk_float *HarmShapeFIR, /* I */ 161 silk_float Tilt, /* I */ 162 silk_float LF_MA_shp, /* I */ 163 silk_float LF_AR_shp, /* I */ 164 opus_int lag, /* I */ 165 opus_int length /* I */ 166 ) 167 { 168 opus_int i; 169 opus_int idx, LTP_shp_buf_idx; 170 silk_float n_Tilt, n_LF, n_LTP; 171 silk_float sLF_AR_shp, sLF_MA_shp; 172 silk_float *LTP_shp_buf; 173 174 /* To speed up use temp variables instead of using the struct */ 175 LTP_shp_buf = P->sLTP_shp; 176 LTP_shp_buf_idx = P->sLTP_shp_buf_idx; 177 sLF_AR_shp = P->sLF_AR_shp; 178 sLF_MA_shp = P->sLF_MA_shp; 179 180 for( i = 0; i < length; i++ ) { 181 if( lag > 0 ) { 182 silk_assert( HARM_SHAPE_FIR_TAPS == 3 ); 183 idx = lag + LTP_shp_buf_idx; 184 n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ]; 185 n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ]; 186 n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ]; 187 } else { 188 n_LTP = 0; 189 } 190 191 n_Tilt = sLF_AR_shp * Tilt; 192 n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp; 193 194 sLF_AR_shp = st_res[ i ] - n_Tilt; 195 sLF_MA_shp = sLF_AR_shp - n_LF; 196 197 LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; 198 LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp; 199 200 xw[ i ] = sLF_MA_shp - n_LTP; 201 } 202 /* Copy temp variable back to state */ 203 P->sLF_AR_shp = sLF_AR_shp; 204 P->sLF_MA_shp = sLF_MA_shp; 205 P->sLTP_shp_buf_idx = LTP_shp_buf_idx; 206 } 207