2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
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.
21 #include "filterbank_internal.h"
26 #include "filterbank_tables.h"
29 // Declare a function pointer.
30 AllpassFilter2FixDec16 WebRtcIsacfix_AllpassFilter2FixDec16;
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
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];
46 // Assembly file assumption.
47 assert(length % 2 == 0);
49 for (n = 0; n < length; n++) {
52 a = WEBRTC_SPL_MUL_16_16(factor_ch1[0], in_out); // Q15 * Q0 = Q15
53 a <<= 1; // Q15 -> Q16
54 b = WebRtcSpl_AddSatW32(a, state0_ch1);
55 a = WEBRTC_SPL_MUL_16_16(-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
59 a = WEBRTC_SPL_MUL_16_16(factor_ch1[1], in_out); // Q15 * Q0 = Q15
60 a <<= 1; // Q15 -> Q16
61 b = WebRtcSpl_AddSatW32(a, state1_ch1); // Q16
62 a = WEBRTC_SPL_MUL_16_16(-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
68 a = WEBRTC_SPL_MUL_16_16(factor_ch2[0], in_out); // Q15 * Q0 = Q15
69 a <<= 1; // Q15 -> Q16
70 b = WebRtcSpl_AddSatW32(a, state0_ch2); // Q16
71 a = WEBRTC_SPL_MUL_16_16(-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
75 a = WEBRTC_SPL_MUL_16_16(factor_ch2[1], in_out); // Q15 * Q0 = Q15
76 a <<= 1; // Q15 -> Q16
77 b = WebRtcSpl_AddSatW32(a, state1_ch2); // Q16
78 a = WEBRTC_SPL_MUL_16_16(-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
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;
89 // Declare a function pointer.
90 HighpassFilterFixDec32 WebRtcIsacfix_HighpassFilterFixDec32;
92 void WebRtcIsacfix_HighpassFilterFixDec32C(int16_t *io,
94 const int16_t *coefficient,
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];
103 for (k=0; k<len; k++) {
106 #ifdef WEBRTC_ARCH_ARM_V7
108 register int tmp_coeff0;
109 register int tmp_coeff1;
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"
123 [tmp_coeff0]"=&r"(tmp_coeff0),
124 [tmp_coeff1]"=&r"(tmp_coeff1)
125 :[coeff]"r"(coefficient),
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);
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);
144 c = ((int32_t)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7); // Q0
145 io[k] = (int16_t)WebRtcSpl_SatW32ToW16(c); // Write output as Q0.
147 c = WEBRTC_SPL_LSHIFT_W32((int32_t)in, 2) - a2 - b2; // In Q2.
148 c = (int32_t)WEBRTC_SPL_SAT(536870911, c, -536870912);
151 state0 = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4
158 void WebRtcIsacfix_SplitAndFilter1(int16_t *pin,
161 PreFiltBankstr *prefiltdata)
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'. */
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 */
174 /* High pass filter */
175 WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
179 for (k=0;k<FRAMESAMPLES/2;k++) {
180 tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
182 for (k=0;k<QLOOKAHEAD;k++) {
183 tempin_ch1[k]=prefiltdata->INLABUF1_fix[k];
184 prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
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[WEBRTC_SPL_MUL_16_16(2, k)];
192 for (k=0;k<QLOOKAHEAD;k++) {
193 tempin_ch2[k]=prefiltdata->INLABUF2_fix[k];
194 prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
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,
203 WebRtcIsacfix_kUpperApFactorsQ15,
204 WebRtcIsacfix_kLowerApFactorsQ15,
206 prefiltdata->INSTAT1_fix,
207 prefiltdata->INSTAT2_fix);
209 for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) {
210 tmpState_ch1[k] = prefiltdata->INSTAT1_fix[k];
211 tmpState_ch2[k] = prefiltdata->INSTAT2_fix[k];
213 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,
214 tempin_ch2 + FRAMESAMPLES/2,
215 WebRtcIsacfix_kUpperApFactorsQ15,
216 WebRtcIsacfix_kLowerApFactorsQ15,
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 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
227 LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
228 tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
229 HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
232 }/*end of WebRtcIsacfix_SplitAndFilter */
235 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
237 /* Without lookahead */
238 void WebRtcIsacfix_SplitAndFilter2(int16_t *pin,
241 PreFiltBankstr *prefiltdata)
243 /* Function WebRtcIsacfix_SplitAndFilter2 */
244 /* This function creates low-pass and high-pass decimated versions of part of
249 int16_t tempin_ch1[FRAMESAMPLES/2];
250 int16_t tempin_ch2[FRAMESAMPLES/2];
253 /* High pass filter */
254 WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
258 for (k=0;k<FRAMESAMPLES/2;k++) {
259 tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
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[WEBRTC_SPL_MUL_16_16(2, k)];
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,
274 WebRtcIsacfix_kUpperApFactorsQ15,
275 WebRtcIsacfix_kLowerApFactorsQ15,
277 prefiltdata->INSTAT1_fix,
278 prefiltdata->INSTAT2_fix);
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 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
286 LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
287 tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
288 HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
291 }/*end of WebRtcIsacfix_SplitAndFilter */
297 //////////////////////////////////////////////////////////
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 */
306 inLP: a length FRAMESAMPLES/2 array of input low-pass
308 inHP: a length FRAMESAMPLES/2 array of input high-pass
310 postfiltdata: input data structure containing the filterbank
311 states from the previous decoding iteration.
313 Out: a length FRAMESAMPLES array of output reconstructed
314 samples (fullband) based on the input low-pass and
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,
321 PostFiltBankstr *postfiltdata)
324 int16_t in[FRAMESAMPLES];
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.
334 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
336 WebRtcIsacfix_kLowerApFactorsQ15,
337 WebRtcIsacfix_kUpperApFactorsQ15,
339 postfiltdata->STATE_0_UPPER_fix,
340 postfiltdata->STATE_0_LOWER_fix);
342 /* Merge outputs to form the full length output signal.*/
343 for (k=0;k<FRAMESAMPLES/2;k++) {
344 in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
345 in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
348 /* High pass filter */
349 WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
350 WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
352 for (k=0;k<FRAMESAMPLES;k++) {
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 */
366 inLP: a length len/2 array of input low-pass
368 inHP: a length len/2 array of input high-pass
370 postfiltdata: input data structure containing the filterbank
371 states from the previous decoding iteration.
373 Out: a length len array of output reconstructed
374 samples (fullband) based on the input low-pass and
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,
381 PostFiltBankstr *postfiltdata,
385 int16_t in[FRAMESAMPLES];
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.
395 WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
397 WebRtcIsacfix_kLowerApFactorsQ15,
398 WebRtcIsacfix_kUpperApFactorsQ15,
400 postfiltdata->STATE_0_UPPER_fix,
401 postfiltdata->STATE_0_LOWER_fix);
403 /* Merge outputs to form the full length output signal.*/
404 for (k=0;k<len/2;k++) {
405 in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
406 in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
409 /* High pass filter */
410 WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
411 WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
413 for (k=0;k<len;k++) {