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