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