1 /*
2 * Copyright (c) 2011 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 WebRtcIsac_AllPassFilter2Float,
15 * WebRtcIsac_SplitAndFilter, and WebRtcIsac_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/main/source/settings.h"
22 #include "modules/audio_coding/codecs/isac/main/source/codec.h"
23 #include "modules/audio_coding/codecs/isac/main/source/isac_vad.h"
24
25 /* Combining */
26
27 /* HPstcoeff_out_1 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
28 static const float kHpStCoefOut1Float[4] =
29 {-1.99701049409000f, 0.99714204490000f, 0.01701049409000f, -0.01704204490000f};
30
31 /* HPstcoeff_out_2 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
32 static const float kHpStCoefOut2Float[4] =
33 {-1.98645294509837f, 0.98672435560000f, 0.00645294509837f, -0.00662435560000f};
34
35
36 /* Function WebRtcIsac_FilterAndCombine */
37 /* This is a decoder function that takes the decimated
38 length FRAMESAMPLES_HALF input low-pass and
39 high-pass signals and creates a reconstructed fullband
40 output signal of length FRAMESAMPLES. WebRtcIsac_FilterAndCombine
41 is the sibling function of WebRtcIsac_SplitAndFilter */
42 /* INPUTS:
43 inLP: a length FRAMESAMPLES_HALF array of input low-pass
44 samples.
45 inHP: a length FRAMESAMPLES_HALF array of input high-pass
46 samples.
47 postfiltdata: input data structure containing the filterbank
48 states from the previous decoding iteration.
49 OUTPUTS:
50 Out: a length FRAMESAMPLES array of output reconstructed
51 samples (fullband) based on the input low-pass and
52 high-pass signals.
53 postfiltdata: the input data structure containing the filterbank
54 states is updated for the next decoding iteration */
WebRtcIsac_FilterAndCombineFloat(float * InLP,float * InHP,float * Out,PostFiltBankstr * postfiltdata)55 void WebRtcIsac_FilterAndCombineFloat(float *InLP,
56 float *InHP,
57 float *Out,
58 PostFiltBankstr *postfiltdata)
59 {
60 int k;
61 float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
62 float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
63 float ftmp, ftmp2;
64
65 /* Form the polyphase signals*/
66 for (k=0;k<FRAMESAMPLES_HALF;k++) {
67 tempin_ch1[k]=InLP[k]+InHP[k]; /* Construct a new upper channel signal*/
68 tempin_ch2[k]=InLP[k]-InHP[k]; /* Construct a new lower channel signal*/
69 }
70
71
72 /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
73 that were used as a lower channel at the encoding side. So at the decoder, the
74 corresponding all-pass filter factors for each channel are swapped.*/
75 WebRtcIsac_AllPassFilter2Float(tempin_ch1, WebRtcIsac_kLowerApFactorsFloat,
76 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_float);
77
78 /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
79 at the decoder are swapped from the ones at the encoder, the 'upper' channel
80 all-pass filter factors (WebRtcIsac_kUpperApFactorsFloat) are used to filter this new
81 lower channel signal */
82 WebRtcIsac_AllPassFilter2Float(tempin_ch2, WebRtcIsac_kUpperApFactorsFloat,
83 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_float);
84
85
86 /* Merge outputs to form the full length output signal.*/
87 for (k=0;k<FRAMESAMPLES_HALF;k++) {
88 Out[2*k]=tempin_ch2[k];
89 Out[2*k+1]=tempin_ch1[k];
90 }
91
92
93 /* High pass filter */
94
95 for (k=0;k<FRAMESAMPLES;k++) {
96 ftmp2 = Out[k] + kHpStCoefOut1Float[2] * postfiltdata->HPstates1_float[0] +
97 kHpStCoefOut1Float[3] * postfiltdata->HPstates1_float[1];
98 ftmp = Out[k] - kHpStCoefOut1Float[0] * postfiltdata->HPstates1_float[0] -
99 kHpStCoefOut1Float[1] * postfiltdata->HPstates1_float[1];
100 postfiltdata->HPstates1_float[1] = postfiltdata->HPstates1_float[0];
101 postfiltdata->HPstates1_float[0] = ftmp;
102 Out[k] = ftmp2;
103 }
104
105 for (k=0;k<FRAMESAMPLES;k++) {
106 ftmp2 = Out[k] + kHpStCoefOut2Float[2] * postfiltdata->HPstates2_float[0] +
107 kHpStCoefOut2Float[3] * postfiltdata->HPstates2_float[1];
108 ftmp = Out[k] - kHpStCoefOut2Float[0] * postfiltdata->HPstates2_float[0] -
109 kHpStCoefOut2Float[1] * postfiltdata->HPstates2_float[1];
110 postfiltdata->HPstates2_float[1] = postfiltdata->HPstates2_float[0];
111 postfiltdata->HPstates2_float[0] = ftmp;
112 Out[k] = ftmp2;
113 }
114 }
115