• 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 "modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h"
22 
23 #include "modules/audio_coding/codecs/isac/fix/source/codec.h"
24 #include "modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h"
25 #include "modules/audio_coding/codecs/isac/fix/source/settings.h"
26 #include "rtc_base/checks.h"
27 
28 // Declare a function pointer.
29 AllpassFilter2FixDec16 WebRtcIsacfix_AllpassFilter2FixDec16;
30 
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)31 void WebRtcIsacfix_AllpassFilter2FixDec16C(
32     int16_t *data_ch1,  // Input and output in channel 1, in Q0
33     int16_t *data_ch2,  // Input and output in channel 2, in Q0
34     const int16_t *factor_ch1,  // Scaling factor for channel 1, in Q15
35     const int16_t *factor_ch2,  // Scaling factor for channel 2, in Q15
36     const int length,  // Length of the data buffers
37     int32_t *filter_state_ch1,  // Filter state for channel 1, in Q16
38     int32_t *filter_state_ch2) {  // Filter state for channel 2, in Q16
39   int n = 0;
40   int32_t state0_ch1 = filter_state_ch1[0], state1_ch1 = filter_state_ch1[1];
41   int32_t state0_ch2 = filter_state_ch2[0], state1_ch2 = filter_state_ch2[1];
42   int16_t in_out = 0;
43   int32_t a = 0, b = 0;
44 
45   // Assembly file assumption.
46   RTC_DCHECK_EQ(0, length % 2);
47 
48   for (n = 0; n < length; n++) {
49     // Process channel 1:
50     in_out = data_ch1[n];
51     a = factor_ch1[0] * in_out;  // Q15 * Q0 = Q15
52     a *= 1 << 1;  // Q15 -> Q16
53     b = WebRtcSpl_AddSatW32(a, state0_ch1);
54     a = -factor_ch1[0] * (int16_t)(b >> 16);  // Q15
55     state0_ch1 =
56         WebRtcSpl_AddSatW32(a * (1 << 1), (int32_t)in_out * (1 << 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 << 1; // Q15 -> Q16
61     b = WebRtcSpl_AddSatW32(a, state1_ch1);  // Q16
62     a = -factor_ch1[1] * (int16_t)(b >> 16);  // Q15
63     state1_ch1 =
64         WebRtcSpl_AddSatW32(a * (1 << 1), (int32_t)in_out * (1 << 16));  // Q16
65     data_ch1[n] = (int16_t) (b >> 16);  // Save as Q0
66 
67     // Process channel 2:
68     in_out = data_ch2[n];
69     a = factor_ch2[0] * in_out;  // Q15 * Q0 = Q15
70     a *= 1 << 1;  // Q15 -> Q16
71     b = WebRtcSpl_AddSatW32(a, state0_ch2);  // Q16
72     a = -factor_ch2[0] * (int16_t)(b >> 16);  // Q15
73     state0_ch2 =
74         WebRtcSpl_AddSatW32(a * (1 << 1), (int32_t)in_out * (1 << 16));  // Q16
75     in_out = (int16_t) (b >> 16);  // Save as Q0
76 
77     a = factor_ch2[1] * in_out;  // Q15 * Q0 = Q15
78     a *= (1 << 1);  // Q15 -> Q16
79     b = WebRtcSpl_AddSatW32(a, state1_ch2);  // Q16
80     a = -factor_ch2[1] * (int16_t)(b >> 16);  // Q15
81     state1_ch2 =
82         WebRtcSpl_AddSatW32(a * (1 << 1), (int32_t)in_out * (1 << 16));  // Q16
83     data_ch2[n] = (int16_t) (b >> 16);  // Save as Q0
84   }
85 
86   filter_state_ch1[0] = state0_ch1;
87   filter_state_ch1[1] = state1_ch1;
88   filter_state_ch2[0] = state0_ch2;
89   filter_state_ch2[1] = state1_ch2;
90 }
91 
92 // Declare a function pointer.
93 HighpassFilterFixDec32 WebRtcIsacfix_HighpassFilterFixDec32;
94 
WebRtcIsacfix_HighpassFilterFixDec32C(int16_t * io,int16_t len,const int16_t * coefficient,int32_t * state)95 void WebRtcIsacfix_HighpassFilterFixDec32C(int16_t *io,
96                                            int16_t len,
97                                            const int16_t *coefficient,
98                                            int32_t *state)
99 {
100   int k;
101   int32_t a1 = 0, b1 = 0, c = 0, in = 0;
102   int32_t a2 = 0, b2 = 0;
103   int32_t state0 = state[0];
104   int32_t state1 = state[1];
105 
106   for (k=0; k<len; k++) {
107     in = (int32_t)io[k];
108 
109 #ifdef WEBRTC_ARCH_ARM_V7
110     {
111       register int tmp_coeff0;
112       register int tmp_coeff1;
113       __asm __volatile(
114         "ldr %[tmp_coeff0], [%[coeff]]\n\t"
115         "ldr %[tmp_coeff1], [%[coeff], #4]\n\t"
116         "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t"
117         "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t"
118         "ldr %[tmp_coeff0], [%[coeff], #8]\n\t"
119         "ldr %[tmp_coeff1], [%[coeff], #12]\n\t"
120         "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t"
121         "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t"
122         :[a2]"=&r"(a2),
123          [b2]"=&r"(b2),
124          [a1]"=&r"(a1),
125          [b1]"=r"(b1),
126          [tmp_coeff0]"=&r"(tmp_coeff0),
127          [tmp_coeff1]"=&r"(tmp_coeff1)
128         :[coeff]"r"(coefficient),
129          [state0]"r"(state0),
130          [state1]"r"(state1)
131       );
132     }
133 #else
134     /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
135     a1 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[5], state0) +
136         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[4], state0) >> 16);
137     b1 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[7], state1) +
138         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[6], state1) >> 16);
139 
140     /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */
141     a2 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[1], state0) +
142         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[0], state0) >> 16);
143     b2 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[3], state1) +
144         (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[2], state1) >> 16);
145 #endif
146 
147     c = in + ((a1 + b1) >> 7);  // Q0.
148     io[k] = (int16_t)WebRtcSpl_SatW32ToW16(c);  // Write output as Q0.
149 
150     c = in * (1 << 2) - a2 - b2;  // In Q2.
151     c = (int32_t)WEBRTC_SPL_SAT(536870911, c, -536870912);
152 
153     state1 = state0;
154     state0 = c * (1 << 2);  // Write state as Q4
155   }
156   state[0] = state0;
157   state[1] = state1;
158 }
159 
160 
WebRtcIsacfix_SplitAndFilter1(int16_t * pin,int16_t * LP16,int16_t * HP16,PreFiltBankstr * prefiltdata)161 void WebRtcIsacfix_SplitAndFilter1(int16_t *pin,
162                                    int16_t *LP16,
163                                    int16_t *HP16,
164                                    PreFiltBankstr *prefiltdata)
165 {
166   /* Function WebRtcIsacfix_SplitAndFilter */
167   /* This function creates low-pass and high-pass decimated versions of part of
168      the input signal, and part of the signal in the input 'lookahead buffer'. */
169 
170   int k;
171 
172   int16_t tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD];
173   int16_t tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD];
174   int32_t tmpState_ch1[2 * (QORDER-1)]; /* 4 */
175   int32_t tmpState_ch2[2 * (QORDER-1)]; /* 4 */
176 
177   /* High pass filter */
178   WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
179 
180 
181   /* First Channel */
182   for (k=0;k<FRAMESAMPLES/2;k++) {
183     tempin_ch1[QLOOKAHEAD + k] = pin[1 + 2 * k];
184   }
185   for (k=0;k<QLOOKAHEAD;k++) {
186     tempin_ch1[k]=prefiltdata->INLABUF1_fix[k];
187     prefiltdata->INLABUF1_fix[k] = pin[FRAMESAMPLES + 1 - 2 * (QLOOKAHEAD - k)];
188   }
189 
190   /* Second Channel.  This is exactly like the first channel, except that the
191      even samples are now filtered instead (lower channel). */
192   for (k=0;k<FRAMESAMPLES/2;k++) {
193     tempin_ch2[QLOOKAHEAD + k] = pin[2 * k];
194   }
195   for (k=0;k<QLOOKAHEAD;k++) {
196     tempin_ch2[k]=prefiltdata->INLABUF2_fix[k];
197     prefiltdata->INLABUF2_fix[k] = pin[FRAMESAMPLES - 2 * (QLOOKAHEAD - k)];
198   }
199 
200 
201   /*obtain polyphase components by forward all-pass filtering through each channel */
202   /* The all pass filtering automatically updates the filter states which are exported in the
203      prefiltdata structure */
204   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
205                                        tempin_ch2,
206                                        WebRtcIsacfix_kUpperApFactorsQ15,
207                                        WebRtcIsacfix_kLowerApFactorsQ15,
208                                        FRAMESAMPLES/2,
209                                        prefiltdata->INSTAT1_fix,
210                                        prefiltdata->INSTAT2_fix);
211 
212   for (k = 0; k < 2 * (QORDER - 1); k++) {
213     tmpState_ch1[k] = prefiltdata->INSTAT1_fix[k];
214     tmpState_ch2[k] = prefiltdata->INSTAT2_fix[k];
215   }
216   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,
217                                        tempin_ch2 + FRAMESAMPLES/2,
218                                        WebRtcIsacfix_kUpperApFactorsQ15,
219                                        WebRtcIsacfix_kLowerApFactorsQ15,
220                                        QLOOKAHEAD,
221                                        tmpState_ch1,
222                                        tmpState_ch2);
223 
224   /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
225   for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) {
226     int32_t tmp1, tmp2, tmp3;
227     tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0
228     tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0
229     tmp3 = (tmp1 + tmp2) >> 1;  /* Low pass signal. */
230     LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
231     tmp3 = (tmp1 - tmp2) >> 1;  /* High pass signal. */
232     HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
233   }
234 
235 }/*end of WebRtcIsacfix_SplitAndFilter */
236 
237 
238 
239 //////////////////////////////////////////////////////////
240 ////////// Combining
241 /* Function WebRtcIsacfix_FilterAndCombine */
242 /* This is a decoder function that takes the decimated
243    length FRAMESAMPLES/2 input low-pass and
244    high-pass signals and creates a reconstructed fullband
245    output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine
246    is the sibling function of WebRtcIsacfix_SplitAndFilter */
247 /* INPUTS:
248    inLP: a length FRAMESAMPLES/2 array of input low-pass
249    samples.
250    inHP: a length FRAMESAMPLES/2 array of input high-pass
251    samples.
252    postfiltdata: input data structure containing the filterbank
253    states from the previous decoding iteration.
254    OUTPUTS:
255    Out: a length FRAMESAMPLES array of output reconstructed
256    samples (fullband) based on the input low-pass and
257    high-pass signals.
258    postfiltdata: the input data structure containing the filterbank
259    states is updated for the next decoding iteration */
WebRtcIsacfix_FilterAndCombine1(int16_t * tempin_ch1,int16_t * tempin_ch2,int16_t * out16,PostFiltBankstr * postfiltdata)260 void WebRtcIsacfix_FilterAndCombine1(int16_t *tempin_ch1,
261                                      int16_t *tempin_ch2,
262                                      int16_t *out16,
263                                      PostFiltBankstr *postfiltdata)
264 {
265   int k;
266   int16_t in[FRAMESAMPLES];
267 
268   /* all-pass filter the new upper and lower channel signal.
269      For upper channel, use the all-pass filter factors that were used as a
270      lower channel at the encoding side. So at the decoder, the corresponding
271      all-pass filter factors for each channel are swapped.
272      For lower channel signal, since all-pass filter factors at the decoder are
273      swapped from the ones at the encoder, the 'upper' channel all-pass filter
274      factors (kUpperApFactors) are used to filter this new lower channel signal.
275   */
276   WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
277                                        tempin_ch2,
278                                        WebRtcIsacfix_kLowerApFactorsQ15,
279                                        WebRtcIsacfix_kUpperApFactorsQ15,
280                                        FRAMESAMPLES/2,
281                                        postfiltdata->STATE_0_UPPER_fix,
282                                        postfiltdata->STATE_0_LOWER_fix);
283 
284   /* Merge outputs to form the full length output signal.*/
285   for (k=0;k<FRAMESAMPLES/2;k++) {
286     in[2 * k] = tempin_ch2[k];
287     in[2 * k + 1] = tempin_ch1[k];
288   }
289 
290   /* High pass filter */
291   WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
292   WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
293 
294   for (k=0;k<FRAMESAMPLES;k++) {
295     out16[k] = in[k];
296   }
297 }
298