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
27static 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
53void 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
115void 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 */
186void 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 */
262void 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 */
318void 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