• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
WebRtcIsacfix_AllpassFilter2FixDec16C(int16_t * data_ch1,int16_t * data_ch2,const int16_t * factor_ch1,const int16_t * factor_ch2,const int length,int32_t * filter_state_ch1,int32_t * filter_state_ch2)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 
WebRtcIsacfix_HighpassFilterFixDec32C(int16_t * io,int16_t len,const int16_t * coefficient,int32_t * state)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 
WebRtcIsacfix_SplitAndFilter1(int16_t * pin,int16_t * LP16,int16_t * HP16,PreFiltBankstr * prefiltdata)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 */
WebRtcIsacfix_SplitAndFilter2(int16_t * pin,int16_t * LP16,int16_t * HP16,PreFiltBankstr * prefiltdata)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 */
WebRtcIsacfix_FilterAndCombine1(int16_t * tempin_ch1,int16_t * tempin_ch2,int16_t * out16,PostFiltBankstr * postfiltdata)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 */
WebRtcIsacfix_FilterAndCombine2(int16_t * tempin_ch1,int16_t * tempin_ch2,int16_t * out16,PostFiltBankstr * postfiltdata,int16_t len)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