Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks.c @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 16.1 KB
Line 
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.
30AllpassFilter2FixDec16 WebRtcIsacfix_AllpassFilter2FixDec16;
31
32void 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 = WEBRTC_SPL_MUL_16_16(factor_ch1[0], in_out);  // Q15 * Q0 = Q15
53    a <<= 1;  // Q15 -> Q16
54    b = WEBRTC_SPL_ADD_SAT_W32(a, state0_ch1);
55    a = WEBRTC_SPL_MUL_16_16(-factor_ch1[0], (int16_t) (b >> 16));  // Q15
56    state0_ch1 = WEBRTC_SPL_ADD_SAT_W32(a << 1, (uint32_t)in_out << 16);  // Q16
57    in_out = (int16_t) (b >> 16);  // Save as Q0
58
59    a = WEBRTC_SPL_MUL_16_16(factor_ch1[1], in_out);  // Q15 * Q0 = Q15
60    a <<= 1; // Q15 -> Q16
61    b = WEBRTC_SPL_ADD_SAT_W32(a, state1_ch1);  // Q16
62    a = WEBRTC_SPL_MUL_16_16(-factor_ch1[1], (int16_t) (b >> 16));  // Q15
63    state1_ch1 = WEBRTC_SPL_ADD_SAT_W32(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 = WEBRTC_SPL_MUL_16_16(factor_ch2[0], in_out);  // Q15 * Q0 = Q15
69    a <<= 1;  // Q15 -> Q16
70    b = WEBRTC_SPL_ADD_SAT_W32(a, state0_ch2);  // Q16
71    a = WEBRTC_SPL_MUL_16_16(-factor_ch2[0], (int16_t) (b >> 16));  // Q15
72    state0_ch2 = WEBRTC_SPL_ADD_SAT_W32(a << 1, (uint32_t)in_out << 16);  // Q16
73    in_out = (int16_t) (b >> 16);  // Save as Q0
74
75    a = WEBRTC_SPL_MUL_16_16(factor_ch2[1], in_out);  // Q15 * Q0 = Q15
76    a <<= 1;  // Q15 -> Q16
77    b = WEBRTC_SPL_ADD_SAT_W32(a, state1_ch2);  // Q16
78    a = WEBRTC_SPL_MUL_16_16(-factor_ch2[1], (int16_t) (b >> 16));  // Q15
79    state1_ch2 = WEBRTC_SPL_ADD_SAT_W32(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
89void WebRtcIsacfix_HighpassFilterFixDec32(int16_t *io,
90                                          int16_t len,
91                                          const int16_t *coefficient,
92                                          int32_t *state)
93{
94  int k;
95  int32_t a1 = 0, b1 = 0, c = 0, in = 0;
96  int32_t a2 = 0, b2 = 0;
97  int32_t state0 = state[0];
98  int32_t state1 = state[1];
99
100  for (k=0; k<len; k++) {
101    in = (int32_t)io[k];
102
103#ifdef WEBRTC_ARCH_ARM_V7
104    {
105      int tmp_coeff0 = 0;
106      int tmp_coeff1 = 0;
107      __asm __volatile(
108        "ldr %[tmp_coeff0], [%[coeff]]\n\t"
109        "ldr %[tmp_coeff1], [%[coeff], #4]\n\t"
110        "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t"
111        "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t"
112        "ldr %[tmp_coeff0], [%[coeff], #8]\n\t"
113        "ldr %[tmp_coeff1], [%[coeff], #12]\n\t"
114        "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t"
115        "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t"
116        :[a2]"+r"(a2),
117         [b2]"+r"(b2),
118         [a1]"+r"(a1),
119         [b1]"+r"(b1),
120         [tmp_coeff0]"+r"(tmp_coeff0),
121         [tmp_coeff1]"+r"(tmp_coeff1)
122        :[coeff]"r"(coefficient),
123         [state0]"r"(state0),
124         [state1]"r"(state1)
125      );
126    }
127#else
128    /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
129    a1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[5], coefficient[4], state0);
130    b1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[7], coefficient[6], state1);
131
132    /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */
133    a2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[1], coefficient[0], state0);
134    b2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[3], coefficient[2], state1);
135#endif
136
137    c = ((int32_t)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7);  // Q0
138    io[k] = (int16_t)WebRtcSpl_SatW32ToW16(c);  // Write output as Q0.
139
140    c = WEBRTC_SPL_LSHIFT_W32((int32_t)in, 2) - a2 - b2;  // In Q2.
141    c = (int32_t)WEBRTC_SPL_SAT(536870911, c, -536870912);
142
143    state1 = state0;
144    state0 = WEBRTC_SPL_LSHIFT_W32(c, 2);  // Write state as Q4
145  }
146  state[0] = state0;
147  state[1] = state1;
148}
149
150
151void WebRtcIsacfix_SplitAndFilter1(int16_t *pin,
152                                   int16_t *LP16,
153                                   int16_t *HP16,
154                                   PreFiltBankstr *prefiltdata)
155{
156  /* Function WebRtcIsacfix_SplitAndFilter */
157  /* This function creates low-pass and high-pass decimated versions of part of
158     the input signal, and part of the signal in the input 'lookahead buffer'. */
159
160  int k;
161
162  int16_t tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD];
163  int16_t tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD];
164  int32_t tmpState_ch1[2 * (QORDER-1)]; /* 4 */
165  int32_t tmpState_ch2[2 * (QORDER-1)]; /* 4 */
166
167  /* High pass filter */
168  WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
169
170
171  /* First Channel */
172  for (k=0;k<FRAMESAMPLES/2;k++) {
173    tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
174  }
175  for (k=0;k<QLOOKAHEAD;k++) {
176    tempin_ch1[k]=prefiltdata->INLABUF1_fix[k];
177    prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
178  }
179
180  /* Second Channel.  This is exactly like the first channel, except that the
181     even samples are now filtered instead (lower channel). */
182  for (k=0;k<FRAMESAMPLES/2;k++) {
183    tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
184  }
185  for (k=0;k<QLOOKAHEAD;k++) {
186    tempin_ch2[k]=prefiltdata->INLABUF2_fix[k];
187    prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
188  }
189
190
191  /*obtain polyphase components by forward all-pass filtering through each channel */
192  /* The all pass filtering automatically updates the filter states which are exported in the
193     prefiltdata structure */
194  WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
195                                       tempin_ch2,
196                                       WebRtcIsacfix_kUpperApFactorsQ15,
197                                       WebRtcIsacfix_kLowerApFactorsQ15,
198                                       FRAMESAMPLES/2,
199                                       prefiltdata->INSTAT1_fix,
200                                       prefiltdata->INSTAT2_fix);
201
202  for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) {
203    tmpState_ch1[k] = prefiltdata->INSTAT1_fix[k];
204    tmpState_ch2[k] = prefiltdata->INSTAT2_fix[k];
205  }
206  WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,
207                                       tempin_ch2 + FRAMESAMPLES/2,
208                                       WebRtcIsacfix_kUpperApFactorsQ15,
209                                       WebRtcIsacfix_kLowerApFactorsQ15,
210                                       QLOOKAHEAD,
211                                       tmpState_ch1,
212                                       tmpState_ch2);
213
214  /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
215  for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) {
216    int32_t tmp1, tmp2, tmp3;
217    tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0
218    tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0
219    tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
220    LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
221    tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
222    HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
223  }
224
225}/*end of WebRtcIsacfix_SplitAndFilter */
226
227
228#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
229
230/* Without lookahead */
231void WebRtcIsacfix_SplitAndFilter2(int16_t *pin,
232                                   int16_t *LP16,
233                                   int16_t *HP16,
234                                   PreFiltBankstr *prefiltdata)
235{
236  /* Function WebRtcIsacfix_SplitAndFilter2 */
237  /* This function creates low-pass and high-pass decimated versions of part of
238     the input signal. */
239
240  int k;
241
242  int16_t tempin_ch1[FRAMESAMPLES/2];
243  int16_t tempin_ch2[FRAMESAMPLES/2];
244
245
246  /* High pass filter */
247  WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
248
249
250  /* First Channel */
251  for (k=0;k<FRAMESAMPLES/2;k++) {
252    tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
253  }
254
255  /* Second Channel.  This is exactly like the first channel, except that the
256     even samples are now filtered instead (lower channel). */
257  for (k=0;k<FRAMESAMPLES/2;k++) {
258    tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
259  }
260
261
262  /*obtain polyphase components by forward all-pass filtering through each channel */
263  /* The all pass filtering automatically updates the filter states which are exported in the
264     prefiltdata structure */
265  WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
266                                       tempin_ch2,
267                                       WebRtcIsacfix_kUpperApFactorsQ15,
268                                       WebRtcIsacfix_kLowerApFactorsQ15,
269                                       FRAMESAMPLES/2,
270                                       prefiltdata->INSTAT1_fix,
271                                       prefiltdata->INSTAT2_fix);
272
273  /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
274  for (k=0; k<FRAMESAMPLES/2; k++) {
275    int32_t tmp1, tmp2, tmp3;
276    tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0
277    tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0
278    tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
279    LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
280    tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
281    HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
282  }
283
284}/*end of WebRtcIsacfix_SplitAndFilter */
285
286#endif
287
288
289
290//////////////////////////////////////////////////////////
291////////// Combining
292/* Function WebRtcIsacfix_FilterAndCombine */
293/* This is a decoder function that takes the decimated
294   length FRAMESAMPLES/2 input low-pass and
295   high-pass signals and creates a reconstructed fullband
296   output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine
297   is the sibling function of WebRtcIsacfix_SplitAndFilter */
298/* INPUTS:
299   inLP: a length FRAMESAMPLES/2 array of input low-pass
300   samples.
301   inHP: a length FRAMESAMPLES/2 array of input high-pass
302   samples.
303   postfiltdata: input data structure containing the filterbank
304   states from the previous decoding iteration.
305   OUTPUTS:
306   Out: a length FRAMESAMPLES array of output reconstructed
307   samples (fullband) based on the input low-pass and
308   high-pass signals.
309   postfiltdata: the input data structure containing the filterbank
310   states is updated for the next decoding iteration */
311void WebRtcIsacfix_FilterAndCombine1(int16_t *tempin_ch1,
312                                     int16_t *tempin_ch2,
313                                     int16_t *out16,
314                                     PostFiltBankstr *postfiltdata)
315{
316  int k;
317  int16_t in[FRAMESAMPLES];
318
319  /* all-pass filter the new upper and lower channel signal.
320     For upper channel, use the all-pass filter factors that were used as a
321     lower channel at the encoding side. So at the decoder, the corresponding
322     all-pass filter factors for each channel are swapped.
323     For lower channel signal, since all-pass filter factors at the decoder are
324     swapped from the ones at the encoder, the 'upper' channel all-pass filter
325     factors (kUpperApFactors) are used to filter this new lower channel signal.
326  */
327  WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
328                                       tempin_ch2,
329                                       WebRtcIsacfix_kLowerApFactorsQ15,
330                                       WebRtcIsacfix_kUpperApFactorsQ15,
331                                       FRAMESAMPLES/2,
332                                       postfiltdata->STATE_0_UPPER_fix,
333                                       postfiltdata->STATE_0_LOWER_fix);
334
335  /* Merge outputs to form the full length output signal.*/
336  for (k=0;k<FRAMESAMPLES/2;k++) {
337    in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
338    in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
339  }
340
341  /* High pass filter */
342  WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
343  WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
344
345  for (k=0;k<FRAMESAMPLES;k++) {
346    out16[k] = in[k];
347  }
348}
349
350
351#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
352/* Function WebRtcIsacfix_FilterAndCombine */
353/* This is a decoder function that takes the decimated
354   length len/2 input low-pass and
355   high-pass signals and creates a reconstructed fullband
356   output signal of length len. WebRtcIsacfix_FilterAndCombine
357   is the sibling function of WebRtcIsacfix_SplitAndFilter */
358/* INPUTS:
359   inLP: a length len/2 array of input low-pass
360   samples.
361   inHP: a length len/2 array of input high-pass
362   samples.
363   postfiltdata: input data structure containing the filterbank
364   states from the previous decoding iteration.
365   OUTPUTS:
366   Out: a length len array of output reconstructed
367   samples (fullband) based on the input low-pass and
368   high-pass signals.
369   postfiltdata: the input data structure containing the filterbank
370   states is updated for the next decoding iteration */
371void WebRtcIsacfix_FilterAndCombine2(int16_t *tempin_ch1,
372                                     int16_t *tempin_ch2,
373                                     int16_t *out16,
374                                     PostFiltBankstr *postfiltdata,
375                                     int16_t len)
376{
377  int k;
378  int16_t in[FRAMESAMPLES];
379
380  /* all-pass filter the new upper and lower channel signal.
381     For upper channel, use the all-pass filter factors that were used as a
382     lower channel at the encoding side. So at the decoder, the corresponding
383     all-pass filter factors for each channel are swapped.
384     For lower channel signal, since all-pass filter factors at the decoder are
385     swapped from the ones at the encoder, the 'upper' channel all-pass filter
386     factors (kUpperApFactors) are used to filter this new lower channel signal.
387  */
388  WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1,
389                                       tempin_ch2,
390                                       WebRtcIsacfix_kLowerApFactorsQ15,
391                                       WebRtcIsacfix_kUpperApFactorsQ15,
392                                       len / 2,
393                                       postfiltdata->STATE_0_UPPER_fix,
394                                       postfiltdata->STATE_0_LOWER_fix);
395
396  /* Merge outputs to form the full length output signal.*/
397  for (k=0;k<len/2;k++) {
398    in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
399    in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
400  }
401
402  /* High pass filter */
403  WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
404  WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
405
406  for (k=0;k<len;k++) {
407    out16[k] = in[k];
408  }
409}
410
411#endif
Note: See TracBrowser for help on using the repository browser.