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 "filterbank_internal.h" 22 23 #include <assert.h> 24 25 #include "codec.h" 26 #include "filterbank_tables.h" 27 #include "settings.h" 28 29 // Declare a function pointer. 30 AllpassFilter2FixDec16 WebRtcIsacfix_AllpassFilter2FixDec16; 31 32 void WebRtcIsacfix_AllpassFilter2FixDec16C( 33 int16_t *data_ch1, // Input and output in channel 1, in Q0 34 int16_t *data_ch2, // Input and output in channel 2, in Q0 35 const int16_t *factor_ch1, // Scaling factor for channel 1, in Q15 36 const int16_t *factor_ch2, // Scaling factor for channel 2, in Q15 37 const int length, // Length of the data buffers 38 int32_t *filter_state_ch1, // Filter state for channel 1, in Q16 39 int32_t *filter_state_ch2) { // Filter state for channel 2, in Q16 40 int n = 0; 41 int32_t state0_ch1 = filter_state_ch1[0], state1_ch1 = filter_state_ch1[1]; 42 int32_t state0_ch2 = filter_state_ch2[0], state1_ch2 = filter_state_ch2[1]; 43 int16_t in_out = 0; 44 int32_t a = 0, b = 0; 45 46 // Assembly file assumption. 47 assert(length % 2 == 0); 48 49 for (n = 0; n < length; n++) { 50 // Process channel 1: 51 in_out = data_ch1[n]; 52 a = WEBRTC_SPL_MUL_16_16(factor_ch1[0], in_out); // Q15 * Q0 = Q15 53 a <<= 1; // Q15 -> Q16 54 b = WEBRTC_SPL_ADD_SAT_W32(a, state0_ch1); 55 a = WEBRTC_SPL_MUL_16_16(-factor_ch1[0], (int16_t) (b >> 16)); // Q15 56 state0_ch1 = WEBRTC_SPL_ADD_SAT_W32(a << 1, (uint32_t)in_out << 16); // Q16 57 in_out = (int16_t) (b >> 16); // Save as Q0 58 59 a = WEBRTC_SPL_MUL_16_16(factor_ch1[1], in_out); // Q15 * Q0 = Q15 60 a <<= 1; // Q15 -> Q16 61 b = WEBRTC_SPL_ADD_SAT_W32(a, state1_ch1); // Q16 62 a = WEBRTC_SPL_MUL_16_16(-factor_ch1[1], (int16_t) (b >> 16)); // Q15 63 state1_ch1 = WEBRTC_SPL_ADD_SAT_W32(a << 1, (uint32_t)in_out << 16); // Q16 64 data_ch1[n] = (int16_t) (b >> 16); // Save as Q0 65 66 // Process channel 2: 67 in_out = data_ch2[n]; 68 a = WEBRTC_SPL_MUL_16_16(factor_ch2[0], in_out); // Q15 * Q0 = Q15 69 a <<= 1; // Q15 -> Q16 70 b = WEBRTC_SPL_ADD_SAT_W32(a, state0_ch2); // Q16 71 a = WEBRTC_SPL_MUL_16_16(-factor_ch2[0], (int16_t) (b >> 16)); // Q15 72 state0_ch2 = WEBRTC_SPL_ADD_SAT_W32(a << 1, (uint32_t)in_out << 16); // Q16 73 in_out = (int16_t) (b >> 16); // Save as Q0 74 75 a = WEBRTC_SPL_MUL_16_16(factor_ch2[1], in_out); // Q15 * Q0 = Q15 76 a <<= 1; // Q15 -> Q16 77 b = WEBRTC_SPL_ADD_SAT_W32(a, state1_ch2); // Q16 78 a = WEBRTC_SPL_MUL_16_16(-factor_ch2[1], (int16_t) (b >> 16)); // Q15 79 state1_ch2 = WEBRTC_SPL_ADD_SAT_W32(a << 1, (uint32_t)in_out << 16); // Q16 80 data_ch2[n] = (int16_t) (b >> 16); // Save as Q0 81 } 82 83 filter_state_ch1[0] = state0_ch1; 84 filter_state_ch1[1] = state1_ch1; 85 filter_state_ch2[0] = state0_ch2; 86 filter_state_ch2[1] = state1_ch2; 87 } 88 89 void WebRtcIsacfix_HighpassFilterFixDec32(int16_t *io, 90 int16_t len, 91 const int16_t *coefficient, 92 int32_t *state) 93 { 94 int k; 95 int32_t a1 = 0, b1 = 0, c = 0, in = 0; 96 int32_t a2 = 0, b2 = 0; 97 int32_t state0 = state[0]; 98 int32_t state1 = state[1]; 99 100 for (k=0; k<len; k++) { 101 in = (int32_t)io[k]; 102 103 #ifdef WEBRTC_ARCH_ARM_V7 104 { 105 register int tmp_coeff0; 106 register int tmp_coeff1; 107 __asm __volatile( 108 "ldr %[tmp_coeff0], [%[coeff]]\n\t" 109 "ldr %[tmp_coeff1], [%[coeff], #4]\n\t" 110 "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t" 111 "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t" 112 "ldr %[tmp_coeff0], [%[coeff], #8]\n\t" 113 "ldr %[tmp_coeff1], [%[coeff], #12]\n\t" 114 "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t" 115 "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t" 116 :[a2]"=&r"(a2), 117 [b2]"=&r"(b2), 118 [a1]"=&r"(a1), 119 [b1]"=r"(b1), 120 [tmp_coeff0]"=&r"(tmp_coeff0), 121 [tmp_coeff1]"=&r"(tmp_coeff1) 122 :[coeff]"r"(coefficient), 123 [state0]"r"(state0), 124 [state1]"r"(state1) 125 ); 126 } 127 #else 128 /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */ 129 a1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[5], coefficient[4], state0); 130 b1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[7], coefficient[6], state1); 131 132 /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */ 133 a2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[1], coefficient[0], state0); 134 b2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[3], coefficient[2], state1); 135 #endif 136 137 c = ((int32_t)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7); // Q0 138 io[k] = (int16_t)WebRtcSpl_SatW32ToW16(c); // Write output as Q0. 139 140 c = WEBRTC_SPL_LSHIFT_W32((int32_t)in, 2) - a2 - b2; // In Q2. 141 c = (int32_t)WEBRTC_SPL_SAT(536870911, c, -536870912); 142 143 state1 = state0; 144 state0 = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4 145 } 146 state[0] = state0; 147 state[1] = state1; 148 } 149 150 151 void WebRtcIsacfix_SplitAndFilter1(int16_t *pin, 152 int16_t *LP16, 153 int16_t *HP16, 154 PreFiltBankstr *prefiltdata) 155 { 156 /* Function WebRtcIsacfix_SplitAndFilter */ 157 /* This function creates low-pass and high-pass decimated versions of part of 158 the input signal, and part of the signal in the input 'lookahead buffer'. */ 159 160 int k; 161 162 int16_t tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD]; 163 int16_t tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD]; 164 int32_t tmpState_ch1[2 * (QORDER-1)]; /* 4 */ 165 int32_t tmpState_ch2[2 * (QORDER-1)]; /* 4 */ 166 167 /* High pass filter */ 168 WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); 169 170 171 /* First Channel */ 172 for (k=0;k<FRAMESAMPLES/2;k++) { 173 tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; 174 } 175 for (k=0;k<QLOOKAHEAD;k++) { 176 tempin_ch1[k]=prefiltdata->INLABUF1_fix[k]; 177 prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; 178 } 179 180 /* Second Channel. This is exactly like the first channel, except that the 181 even samples are now filtered instead (lower channel). */ 182 for (k=0;k<FRAMESAMPLES/2;k++) { 183 tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; 184 } 185 for (k=0;k<QLOOKAHEAD;k++) { 186 tempin_ch2[k]=prefiltdata->INLABUF2_fix[k]; 187 prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; 188 } 189 190 191 /*obtain polyphase components by forward all-pass filtering through each channel */ 192 /* The all pass filtering automatically updates the filter states which are exported in the 193 prefiltdata structure */ 194 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 195 tempin_ch2, 196 WebRtcIsacfix_kUpperApFactorsQ15, 197 WebRtcIsacfix_kLowerApFactorsQ15, 198 FRAMESAMPLES/2, 199 prefiltdata->INSTAT1_fix, 200 prefiltdata->INSTAT2_fix); 201 202 for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) { 203 tmpState_ch1[k] = prefiltdata->INSTAT1_fix[k]; 204 tmpState_ch2[k] = prefiltdata->INSTAT2_fix[k]; 205 } 206 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2, 207 tempin_ch2 + FRAMESAMPLES/2, 208 WebRtcIsacfix_kUpperApFactorsQ15, 209 WebRtcIsacfix_kLowerApFactorsQ15, 210 QLOOKAHEAD, 211 tmpState_ch1, 212 tmpState_ch2); 213 214 /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ 215 for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) { 216 int32_t tmp1, tmp2, tmp3; 217 tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0 218 tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0 219 tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ 220 LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */ 221 tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ 222 HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */ 223 } 224 225 }/*end of WebRtcIsacfix_SplitAndFilter */ 226 227 228 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED 229 230 /* Without lookahead */ 231 void WebRtcIsacfix_SplitAndFilter2(int16_t *pin, 232 int16_t *LP16, 233 int16_t *HP16, 234 PreFiltBankstr *prefiltdata) 235 { 236 /* Function WebRtcIsacfix_SplitAndFilter2 */ 237 /* This function creates low-pass and high-pass decimated versions of part of 238 the input signal. */ 239 240 int k; 241 242 int16_t tempin_ch1[FRAMESAMPLES/2]; 243 int16_t tempin_ch2[FRAMESAMPLES/2]; 244 245 246 /* High pass filter */ 247 WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); 248 249 250 /* First Channel */ 251 for (k=0;k<FRAMESAMPLES/2;k++) { 252 tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; 253 } 254 255 /* Second Channel. This is exactly like the first channel, except that the 256 even samples are now filtered instead (lower channel). */ 257 for (k=0;k<FRAMESAMPLES/2;k++) { 258 tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; 259 } 260 261 262 /*obtain polyphase components by forward all-pass filtering through each channel */ 263 /* The all pass filtering automatically updates the filter states which are exported in the 264 prefiltdata structure */ 265 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 266 tempin_ch2, 267 WebRtcIsacfix_kUpperApFactorsQ15, 268 WebRtcIsacfix_kLowerApFactorsQ15, 269 FRAMESAMPLES/2, 270 prefiltdata->INSTAT1_fix, 271 prefiltdata->INSTAT2_fix); 272 273 /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ 274 for (k=0; k<FRAMESAMPLES/2; k++) { 275 int32_t tmp1, tmp2, tmp3; 276 tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0 277 tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0 278 tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ 279 LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */ 280 tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ 281 HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */ 282 } 283 284 }/*end of WebRtcIsacfix_SplitAndFilter */ 285 286 #endif 287 288 289 290 ////////////////////////////////////////////////////////// 291 ////////// Combining 292 /* Function WebRtcIsacfix_FilterAndCombine */ 293 /* This is a decoder function that takes the decimated 294 length FRAMESAMPLES/2 input low-pass and 295 high-pass signals and creates a reconstructed fullband 296 output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine 297 is the sibling function of WebRtcIsacfix_SplitAndFilter */ 298 /* INPUTS: 299 inLP: a length FRAMESAMPLES/2 array of input low-pass 300 samples. 301 inHP: a length FRAMESAMPLES/2 array of input high-pass 302 samples. 303 postfiltdata: input data structure containing the filterbank 304 states from the previous decoding iteration. 305 OUTPUTS: 306 Out: a length FRAMESAMPLES array of output reconstructed 307 samples (fullband) based on the input low-pass and 308 high-pass signals. 309 postfiltdata: the input data structure containing the filterbank 310 states is updated for the next decoding iteration */ 311 void WebRtcIsacfix_FilterAndCombine1(int16_t *tempin_ch1, 312 int16_t *tempin_ch2, 313 int16_t *out16, 314 PostFiltBankstr *postfiltdata) 315 { 316 int k; 317 int16_t in[FRAMESAMPLES]; 318 319 /* all-pass filter the new upper and lower channel signal. 320 For upper channel, use the all-pass filter factors that were used as a 321 lower channel at the encoding side. So at the decoder, the corresponding 322 all-pass filter factors for each channel are swapped. 323 For lower channel signal, since all-pass filter factors at the decoder are 324 swapped from the ones at the encoder, the 'upper' channel all-pass filter 325 factors (kUpperApFactors) are used to filter this new lower channel signal. 326 */ 327 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 328 tempin_ch2, 329 WebRtcIsacfix_kLowerApFactorsQ15, 330 WebRtcIsacfix_kUpperApFactorsQ15, 331 FRAMESAMPLES/2, 332 postfiltdata->STATE_0_UPPER_fix, 333 postfiltdata->STATE_0_LOWER_fix); 334 335 /* Merge outputs to form the full length output signal.*/ 336 for (k=0;k<FRAMESAMPLES/2;k++) { 337 in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; 338 in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; 339 } 340 341 /* High pass filter */ 342 WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); 343 WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); 344 345 for (k=0;k<FRAMESAMPLES;k++) { 346 out16[k] = in[k]; 347 } 348 } 349 350 351 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED 352 /* Function WebRtcIsacfix_FilterAndCombine */ 353 /* This is a decoder function that takes the decimated 354 length len/2 input low-pass and 355 high-pass signals and creates a reconstructed fullband 356 output signal of length len. WebRtcIsacfix_FilterAndCombine 357 is the sibling function of WebRtcIsacfix_SplitAndFilter */ 358 /* INPUTS: 359 inLP: a length len/2 array of input low-pass 360 samples. 361 inHP: a length len/2 array of input high-pass 362 samples. 363 postfiltdata: input data structure containing the filterbank 364 states from the previous decoding iteration. 365 OUTPUTS: 366 Out: a length len array of output reconstructed 367 samples (fullband) based on the input low-pass and 368 high-pass signals. 369 postfiltdata: the input data structure containing the filterbank 370 states is updated for the next decoding iteration */ 371 void WebRtcIsacfix_FilterAndCombine2(int16_t *tempin_ch1, 372 int16_t *tempin_ch2, 373 int16_t *out16, 374 PostFiltBankstr *postfiltdata, 375 int16_t len) 376 { 377 int k; 378 int16_t in[FRAMESAMPLES]; 379 380 /* all-pass filter the new upper and lower channel signal. 381 For upper channel, use the all-pass filter factors that were used as a 382 lower channel at the encoding side. So at the decoder, the corresponding 383 all-pass filter factors for each channel are swapped. 384 For lower channel signal, since all-pass filter factors at the decoder are 385 swapped from the ones at the encoder, the 'upper' channel all-pass filter 386 factors (kUpperApFactors) are used to filter this new lower channel signal. 387 */ 388 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 389 tempin_ch2, 390 WebRtcIsacfix_kLowerApFactorsQ15, 391 WebRtcIsacfix_kUpperApFactorsQ15, 392 len / 2, 393 postfiltdata->STATE_0_UPPER_fix, 394 postfiltdata->STATE_0_LOWER_fix); 395 396 /* Merge outputs to form the full length output signal.*/ 397 for (k=0;k<len/2;k++) { 398 in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; 399 in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; 400 } 401 402 /* High pass filter */ 403 WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); 404 WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); 405 406 for (k=0;k<len;k++) { 407 out16[k] = in[k]; 408 } 409 } 410 411 #endif 412