1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 /* 12 * filterbanks.c 13 * 14 * This file contains function 15 * WebRtcIsacfix_SplitAndFilter, and WebRtcIsacfix_FilterAndCombine 16 * which implement filterbanks that produce decimated lowpass and 17 * highpass versions of a signal, and performs reconstruction. 18 * 19 */ 20 21 #include "codec.h" 22 #include "filterbank_internal.h" 23 #include "filterbank_tables.h" 24 #include "settings.h" 25 26 27 static void AllpassFilter2FixDec16(WebRtc_Word16 *InOut16, //Q0 28 const WebRtc_Word16 *APSectionFactors, //Q15 29 WebRtc_Word16 lengthInOut, 30 WebRtc_Word16 NumberOfSections, 31 WebRtc_Word32 *FilterState) //Q16 32 { 33 int n, j; 34 WebRtc_Word32 a, b; 35 36 for (j=0; j<NumberOfSections; j++) { 37 for (n=0;n<lengthInOut;n++) { 38 39 40 a = WEBRTC_SPL_MUL_16_16(APSectionFactors[j], InOut16[n]); //Q15*Q0=Q15 41 a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16 42 b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16 43 a = WEBRTC_SPL_MUL_16_16_RSFT(-APSectionFactors[j], (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16), 0); //Q15*Q0=Q15 44 FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(WEBRTC_SPL_LSHIFT_W32(a,1), WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n],16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16 45 InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0 46 47 } 48 } 49 50 } 51 52 53 void WebRtcIsacfix_HighpassFilterFixDec32(int16_t *io, 54 int16_t len, 55 const int16_t *coefficient, 56 int32_t *state) 57 { 58 int k; 59 WebRtc_Word32 a1 = 0, b1 = 0, c = 0, in = 0; 60 WebRtc_Word32 a2 = 0, b2 = 0; 61 WebRtc_Word32 state0 = state[0]; 62 WebRtc_Word32 state1 = state[1]; 63 64 for (k=0; k<len; k++) { 65 in = (WebRtc_Word32)io[k]; 66 67 #ifdef WEBRTC_ARCH_ARM_V7 68 { 69 int tmp_coeff0 = 0; 70 int tmp_coeff1 = 0; 71 __asm __volatile( 72 "ldr %[tmp_coeff0], [%[coeff]]\n\t" 73 "ldr %[tmp_coeff1], [%[coeff], #4]\n\t" 74 "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t" 75 "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t" 76 "ldr %[tmp_coeff0], [%[coeff], #8]\n\t" 77 "ldr %[tmp_coeff1], [%[coeff], #12]\n\t" 78 "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t" 79 "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t" 80 :[a2]"+r"(a2), 81 [b2]"+r"(b2), 82 [a1]"+r"(a1), 83 [b1]"+r"(b1), 84 [tmp_coeff0]"+r"(tmp_coeff0), 85 [tmp_coeff1]"+r"(tmp_coeff1) 86 :[coeff]"r"(coefficient), 87 [state0]"r"(state0), 88 [state1]"r"(state1) 89 ); 90 } 91 #else 92 /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */ 93 a1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[5], coefficient[4], state0); 94 b1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[7], coefficient[6], state1); 95 96 /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */ 97 a2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[1], coefficient[0], state0); 98 b2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[3], coefficient[2], state1); 99 #endif 100 101 c = ((WebRtc_Word32)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7); // Q0 102 io[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(c); // Write output as Q0. 103 104 c = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in, 2) - a2 - b2; // In Q2. 105 c = (WebRtc_Word32)WEBRTC_SPL_SAT(536870911, c, -536870912); 106 107 state1 = state0; 108 state0 = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4 109 } 110 state[0] = state0; 111 state[1] = state1; 112 } 113 114 115 void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *pin, 116 WebRtc_Word16 *LP16, 117 WebRtc_Word16 *HP16, 118 PreFiltBankstr *prefiltdata) 119 { 120 /* Function WebRtcIsacfix_SplitAndFilter */ 121 /* This function creates low-pass and high-pass decimated versions of part of 122 the input signal, and part of the signal in the input 'lookahead buffer'. */ 123 124 int k; 125 126 WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD]; 127 WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD]; 128 WebRtc_Word32 tmpState[WEBRTC_SPL_MUL_16_16(2,(QORDER-1))]; /* 4 */ 129 130 131 /* High pass filter */ 132 WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); 133 134 135 /* First Channel */ 136 for (k=0;k<FRAMESAMPLES/2;k++) { 137 tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; 138 } 139 for (k=0;k<QLOOKAHEAD;k++) { 140 tempin_ch1[k]=prefiltdata->INLABUF1_fix[k]; 141 prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; 142 } 143 144 /* Second Channel. This is exactly like the first channel, except that the 145 even samples are now filtered instead (lower channel). */ 146 for (k=0;k<FRAMESAMPLES/2;k++) { 147 tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; 148 } 149 for (k=0;k<QLOOKAHEAD;k++) { 150 tempin_ch2[k]=prefiltdata->INLABUF2_fix[k]; 151 prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; 152 } 153 154 155 /*obtain polyphase components by forward all-pass filtering through each channel */ 156 /* The all pass filtering automatically updates the filter states which are exported in the 157 prefiltdata structure */ 158 AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix); 159 AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix); 160 161 for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) 162 tmpState[k] = prefiltdata->INSTAT1_fix[k]; 163 AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,WebRtcIsacfix_kUpperApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState); 164 for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) 165 tmpState[k] = prefiltdata->INSTAT2_fix[k]; 166 AllpassFilter2FixDec16(tempin_ch2 + FRAMESAMPLES/2,WebRtcIsacfix_kLowerApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState); 167 168 169 /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ 170 for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) { 171 WebRtc_Word32 tmp1, tmp2, tmp3; 172 tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0 173 tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0 174 tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ 175 LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */ 176 tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ 177 HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */ 178 } 179 180 }/*end of WebRtcIsacfix_SplitAndFilter */ 181 182 183 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED 184 185 /* Without lookahead */ 186 void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16 *pin, 187 WebRtc_Word16 *LP16, 188 WebRtc_Word16 *HP16, 189 PreFiltBankstr *prefiltdata) 190 { 191 /* Function WebRtcIsacfix_SplitAndFilter2 */ 192 /* This function creates low-pass and high-pass decimated versions of part of 193 the input signal. */ 194 195 int k; 196 197 WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2]; 198 WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2]; 199 200 201 /* High pass filter */ 202 WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); 203 204 205 /* First Channel */ 206 for (k=0;k<FRAMESAMPLES/2;k++) { 207 tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; 208 } 209 210 /* Second Channel. This is exactly like the first channel, except that the 211 even samples are now filtered instead (lower channel). */ 212 for (k=0;k<FRAMESAMPLES/2;k++) { 213 tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; 214 } 215 216 217 /*obtain polyphase components by forward all-pass filtering through each channel */ 218 /* The all pass filtering automatically updates the filter states which are exported in the 219 prefiltdata structure */ 220 AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix); 221 AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix); 222 223 224 /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ 225 for (k=0; k<FRAMESAMPLES/2; k++) { 226 WebRtc_Word32 tmp1, tmp2, tmp3; 227 tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0 228 tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0 229 tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ 230 LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */ 231 tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ 232 HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */ 233 } 234 235 }/*end of WebRtcIsacfix_SplitAndFilter */ 236 237 #endif 238 239 240 241 ////////////////////////////////////////////////////////// 242 ////////// Combining 243 /* Function WebRtcIsacfix_FilterAndCombine */ 244 /* This is a decoder function that takes the decimated 245 length FRAMESAMPLES/2 input low-pass and 246 high-pass signals and creates a reconstructed fullband 247 output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine 248 is the sibling function of WebRtcIsacfix_SplitAndFilter */ 249 /* INPUTS: 250 inLP: a length FRAMESAMPLES/2 array of input low-pass 251 samples. 252 inHP: a length FRAMESAMPLES/2 array of input high-pass 253 samples. 254 postfiltdata: input data structure containing the filterbank 255 states from the previous decoding iteration. 256 OUTPUTS: 257 Out: a length FRAMESAMPLES array of output reconstructed 258 samples (fullband) based on the input low-pass and 259 high-pass signals. 260 postfiltdata: the input data structure containing the filterbank 261 states is updated for the next decoding iteration */ 262 void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16 *tempin_ch1, 263 WebRtc_Word16 *tempin_ch2, 264 WebRtc_Word16 *out16, 265 PostFiltBankstr *postfiltdata) 266 { 267 int k; 268 WebRtc_Word16 in[FRAMESAMPLES]; 269 270 /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors 271 that were used as a lower channel at the encoding side. So at the decoder, the 272 corresponding all-pass filter factors for each channel are swapped.*/ 273 274 AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix); 275 276 /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors 277 at the decoder are swapped from the ones at the encoder, the 'upper' channel 278 all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */ 279 280 AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix); 281 282 /* Merge outputs to form the full length output signal.*/ 283 for (k=0;k<FRAMESAMPLES/2;k++) { 284 in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; 285 in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; 286 } 287 288 /* High pass filter */ 289 WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); 290 WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); 291 292 for (k=0;k<FRAMESAMPLES;k++) { 293 out16[k] = in[k]; 294 } 295 } 296 297 298 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED 299 /* Function WebRtcIsacfix_FilterAndCombine */ 300 /* This is a decoder function that takes the decimated 301 length len/2 input low-pass and 302 high-pass signals and creates a reconstructed fullband 303 output signal of length len. WebRtcIsacfix_FilterAndCombine 304 is the sibling function of WebRtcIsacfix_SplitAndFilter */ 305 /* INPUTS: 306 inLP: a length len/2 array of input low-pass 307 samples. 308 inHP: a length len/2 array of input high-pass 309 samples. 310 postfiltdata: input data structure containing the filterbank 311 states from the previous decoding iteration. 312 OUTPUTS: 313 Out: a length len array of output reconstructed 314 samples (fullband) based on the input low-pass and 315 high-pass signals. 316 postfiltdata: the input data structure containing the filterbank 317 states is updated for the next decoding iteration */ 318 void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1, 319 WebRtc_Word16 *tempin_ch2, 320 WebRtc_Word16 *out16, 321 PostFiltBankstr *postfiltdata, 322 WebRtc_Word16 len) 323 { 324 int k; 325 WebRtc_Word16 in[FRAMESAMPLES]; 326 327 /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors 328 that were used as a lower channel at the encoding side. So at the decoder, the 329 corresponding all-pass filter factors for each channel are swapped.*/ 330 331 AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15,(WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix); 332 333 /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors 334 at the decoder are swapped from the ones at the encoder, the 'upper' channel 335 all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */ 336 337 AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, (WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix); 338 339 /* Merge outputs to form the full length output signal.*/ 340 for (k=0;k<len/2;k++) { 341 in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; 342 in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; 343 } 344 345 /* High pass filter */ 346 WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); 347 WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); 348 349 for (k=0;k<len;k++) { 350 out16[k] = in[k]; 351 } 352 } 353 354 #endif 355