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 "settings.h"
22 #include "filterbank_tables.h"
23 #include "codec.h"
24
25 /* This function performs all-pass filtering--a series of first order all-pass
26 * sections are used to filter the input in a cascade manner.
27 * The input is overwritten!!
28 */
WebRtcIsac_AllPassFilter2Float(float * InOut,const float * APSectionFactors,int lengthInOut,int NumberOfSections,float * FilterState)29 static void WebRtcIsac_AllPassFilter2Float(float *InOut, const float *APSectionFactors,
30 int lengthInOut, int NumberOfSections,
31 float *FilterState)
32 {
33 int n, j;
34 float temp;
35 for (j=0; j<NumberOfSections; j++){
36 for (n=0;n<lengthInOut;n++){
37 temp = FilterState[j] + APSectionFactors[j] * InOut[n];
38 FilterState[j] = -APSectionFactors[j] * temp + InOut[n];
39 InOut[n] = temp;
40 }
41 }
42 }
43
44 /* HPstcoeff_in = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
45 static const float kHpStCoefInFloat[4] =
46 {-1.94895953203325f, 0.94984516000000f, -0.05101826139794f, 0.05015484000000f};
47
48 /* Function WebRtcIsac_SplitAndFilter
49 * This function creates low-pass and high-pass decimated versions of part of
50 the input signal, and part of the signal in the input 'lookahead buffer'.
51
52 INPUTS:
53 in: a length FRAMESAMPLES array of input samples
54 prefiltdata: input data structure containing the filterbank states
55 and lookahead samples from the previous encoding
56 iteration.
57 OUTPUTS:
58 LP: a FRAMESAMPLES_HALF array of low-pass filtered samples that
59 have been phase equalized. The first QLOOKAHEAD samples are
60 based on the samples in the two prefiltdata->INLABUFx arrays
61 each of length QLOOKAHEAD.
62 The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
63 on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
64 array in[].
65 HP: a FRAMESAMPLES_HALF array of high-pass filtered samples that
66 have been phase equalized. The first QLOOKAHEAD samples are
67 based on the samples in the two prefiltdata->INLABUFx arrays
68 each of length QLOOKAHEAD.
69 The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
70 on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
71 array in[].
72
73 LP_la: a FRAMESAMPLES_HALF array of low-pass filtered samples.
74 These samples are not phase equalized. They are computed
75 from the samples in the in[] array.
76 HP_la: a FRAMESAMPLES_HALF array of high-pass filtered samples
77 that are not phase equalized. They are computed from
78 the in[] vector.
79 prefiltdata: this input data structure's filterbank state and
80 lookahead sample buffers are updated for the next
81 encoding iteration.
82 */
WebRtcIsac_SplitAndFilterFloat(float * pin,float * LP,float * HP,double * LP_la,double * HP_la,PreFiltBankstr * prefiltdata)83 void WebRtcIsac_SplitAndFilterFloat(float *pin, float *LP, float *HP,
84 double *LP_la, double *HP_la,
85 PreFiltBankstr *prefiltdata)
86 {
87 int k,n;
88 float CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
89 float ForTransform_CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
90 float ForTransform_CompositeAPFilterState2[NUMBEROFCOMPOSITEAPSECTIONS];
91 float tempinoutvec[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
92 float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
93 float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
94 float in[FRAMESAMPLES];
95 float ftmp;
96
97
98 /* High pass filter */
99
100 for (k=0;k<FRAMESAMPLES;k++) {
101 in[k] = pin[k] + kHpStCoefInFloat[2] * prefiltdata->HPstates_float[0] +
102 kHpStCoefInFloat[3] * prefiltdata->HPstates_float[1];
103 ftmp = pin[k] - kHpStCoefInFloat[0] * prefiltdata->HPstates_float[0] -
104 kHpStCoefInFloat[1] * prefiltdata->HPstates_float[1];
105 prefiltdata->HPstates_float[1] = prefiltdata->HPstates_float[0];
106 prefiltdata->HPstates_float[0] = ftmp;
107 }
108
109 /*
110 % backwards all-pass filtering to obtain zero-phase
111 [tmp1(N2+LA:-1:LA+1, 1), state1] = filter(Q.coef, Q.coef(end:-1:1), in(N:-2:2));
112 tmp1(LA:-1:1) = filter(Q.coef, Q.coef(end:-1:1), Q.LookAheadBuf1, state1);
113 Q.LookAheadBuf1 = in(N:-2:N-2*LA+2);
114 */
115 /*Backwards all-pass filter the odd samples of the input (upper channel)
116 to eventually obtain zero phase. The composite all-pass filter (comprised of both
117 the upper and lower channel all-pass filsters in series) is used for the
118 filtering. */
119
120 /* First Channel */
121
122 /*initial state of composite filter is zero */
123 for (k=0;k<NUMBEROFCOMPOSITEAPSECTIONS;k++){
124 CompositeAPFilterState[k] = 0.0;
125 }
126 /* put every other sample of input into a temporary vector in reverse (backward) order*/
127 for (k=0;k<FRAMESAMPLES_HALF;k++) {
128 tempinoutvec[k] = in[FRAMESAMPLES-1-2*k];
129 }
130
131 /* now all-pass filter the backwards vector. Output values overwrite the input vector. */
132 WebRtcIsac_AllPassFilter2Float(tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat,
133 FRAMESAMPLES_HALF, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
134
135 /* save the backwards filtered output for later forward filtering,
136 but write it in forward order*/
137 for (k=0;k<FRAMESAMPLES_HALF;k++) {
138 tempin_ch1[FRAMESAMPLES_HALF+QLOOKAHEAD-1-k] = tempinoutvec[k];
139 }
140
141 /* save the backwards filter state becaue it will be transformed
142 later into a forward state */
143 for (k=0; k<NUMBEROFCOMPOSITEAPSECTIONS; k++) {
144 ForTransform_CompositeAPFilterState[k] = CompositeAPFilterState[k];
145 }
146
147 /* now backwards filter the samples in the lookahead buffer. The samples were
148 placed there in the encoding of the previous frame. The output samples
149 overwrite the input samples */
150 WebRtcIsac_AllPassFilter2Float(prefiltdata->INLABUF1_float,
151 WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD,
152 NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
153
154 /* save the output, but write it in forward order */
155 /* write the lookahead samples for the next encoding iteration. Every other
156 sample at the end of the input frame is written in reverse order for the
157 lookahead length. Exported in the prefiltdata structure. */
158 for (k=0;k<QLOOKAHEAD;k++) {
159 tempin_ch1[QLOOKAHEAD-1-k]=prefiltdata->INLABUF1_float[k];
160 prefiltdata->INLABUF1_float[k]=in[FRAMESAMPLES-1-2*k];
161 }
162
163 /* Second Channel. This is exactly like the first channel, except that the
164 even samples are now filtered instead (lower channel). */
165 for (k=0;k<NUMBEROFCOMPOSITEAPSECTIONS;k++){
166 CompositeAPFilterState[k] = 0.0;
167 }
168
169 for (k=0;k<FRAMESAMPLES_HALF;k++) {
170 tempinoutvec[k] = in[FRAMESAMPLES-2-2*k];
171 }
172
173 WebRtcIsac_AllPassFilter2Float(tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat,
174 FRAMESAMPLES_HALF, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
175
176 for (k=0;k<FRAMESAMPLES_HALF;k++) {
177 tempin_ch2[FRAMESAMPLES_HALF+QLOOKAHEAD-1-k] = tempinoutvec[k];
178 }
179
180 for (k=0; k<NUMBEROFCOMPOSITEAPSECTIONS; k++) {
181 ForTransform_CompositeAPFilterState2[k] = CompositeAPFilterState[k];
182 }
183
184
185 WebRtcIsac_AllPassFilter2Float(prefiltdata->INLABUF2_float,
186 WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD,NUMBEROFCOMPOSITEAPSECTIONS,
187 CompositeAPFilterState);
188
189 for (k=0;k<QLOOKAHEAD;k++) {
190 tempin_ch2[QLOOKAHEAD-1-k]=prefiltdata->INLABUF2_float[k];
191 prefiltdata->INLABUF2_float[k]=in[FRAMESAMPLES-2-2*k];
192 }
193
194 /* Transform filter states from backward to forward */
195 /*At this point, each of the states of the backwards composite filters for the
196 two channels are transformed into forward filtering states for the corresponding
197 forward channel filters. Each channel's forward filtering state from the previous
198 encoding iteration is added to the transformed state to get a proper forward state */
199
200 /* So the existing NUMBEROFCOMPOSITEAPSECTIONS x 1 (4x1) state vector is multiplied by a
201 NUMBEROFCHANNELAPSECTIONSxNUMBEROFCOMPOSITEAPSECTIONS (2x4) transform matrix to get the
202 new state that is added to the previous 2x1 input state */
203
204 for (k=0;k<NUMBEROFCHANNELAPSECTIONS;k++){ /* k is row variable */
205 for (n=0; n<NUMBEROFCOMPOSITEAPSECTIONS;n++){/* n is column variable */
206 prefiltdata->INSTAT1_float[k] += ForTransform_CompositeAPFilterState[n]*
207 WebRtcIsac_kTransform1Float[k*NUMBEROFCHANNELAPSECTIONS+n];
208 prefiltdata->INSTAT2_float[k] += ForTransform_CompositeAPFilterState2[n]*
209 WebRtcIsac_kTransform2Float[k*NUMBEROFCHANNELAPSECTIONS+n];
210 }
211 }
212
213 /*obtain polyphase components by forward all-pass filtering through each channel */
214 /* the backward filtered samples are now forward filtered with the corresponding channel filters */
215 /* The all pass filtering automatically updates the filter states which are exported in the
216 prefiltdata structure */
217 WebRtcIsac_AllPassFilter2Float(tempin_ch1,WebRtcIsac_kUpperApFactorsFloat,
218 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_float);
219 WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat,
220 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_float);
221
222 /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
223 for (k=0; k<FRAMESAMPLES_HALF; k++) {
224 LP[k] = 0.5f*(tempin_ch1[k] + tempin_ch2[k]);/* low pass signal*/
225 HP[k] = 0.5f*(tempin_ch1[k] - tempin_ch2[k]);/* high pass signal*/
226 }
227
228 /* Lookahead LP and HP signals */
229 /* now create low pass and high pass signals of the input vector. However, no
230 backwards filtering is performed, and hence no phase equalization is involved.
231 Also, the input contains some samples that are lookahead samples. The high pass
232 and low pass signals that are created are used outside this function for analysis
233 (not encoding) purposes */
234
235 /* set up input */
236 for (k=0; k<FRAMESAMPLES_HALF; k++) {
237 tempin_ch1[k]=in[2*k+1];
238 tempin_ch2[k]=in[2*k];
239 }
240
241 /* the input filter states are passed in and updated by the all-pass filtering routine and
242 exported in the prefiltdata structure*/
243 WebRtcIsac_AllPassFilter2Float(tempin_ch1,WebRtcIsac_kUpperApFactorsFloat,
244 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTATLA1_float);
245 WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat,
246 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTATLA2_float);
247
248 for (k=0; k<FRAMESAMPLES_HALF; k++) {
249 LP_la[k] = (float)(0.5f*(tempin_ch1[k] + tempin_ch2[k])); /*low pass */
250 HP_la[k] = (double)(0.5f*(tempin_ch1[k] - tempin_ch2[k])); /* high pass */
251 }
252
253
254 }/*end of WebRtcIsac_SplitAndFilter */
255
256
257 /* Combining */
258
259 /* HPstcoeff_out_1 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
260 static const float kHpStCoefOut1Float[4] =
261 {-1.99701049409000f, 0.99714204490000f, 0.01701049409000f, -0.01704204490000f};
262
263 /* HPstcoeff_out_2 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
264 static const float kHpStCoefOut2Float[4] =
265 {-1.98645294509837f, 0.98672435560000f, 0.00645294509837f, -0.00662435560000f};
266
267
268 /* Function WebRtcIsac_FilterAndCombine */
269 /* This is a decoder function that takes the decimated
270 length FRAMESAMPLES_HALF input low-pass and
271 high-pass signals and creates a reconstructed fullband
272 output signal of length FRAMESAMPLES. WebRtcIsac_FilterAndCombine
273 is the sibling function of WebRtcIsac_SplitAndFilter */
274 /* INPUTS:
275 inLP: a length FRAMESAMPLES_HALF array of input low-pass
276 samples.
277 inHP: a length FRAMESAMPLES_HALF array of input high-pass
278 samples.
279 postfiltdata: input data structure containing the filterbank
280 states from the previous decoding iteration.
281 OUTPUTS:
282 Out: a length FRAMESAMPLES array of output reconstructed
283 samples (fullband) based on the input low-pass and
284 high-pass signals.
285 postfiltdata: the input data structure containing the filterbank
286 states is updated for the next decoding iteration */
WebRtcIsac_FilterAndCombineFloat(float * InLP,float * InHP,float * Out,PostFiltBankstr * postfiltdata)287 void WebRtcIsac_FilterAndCombineFloat(float *InLP,
288 float *InHP,
289 float *Out,
290 PostFiltBankstr *postfiltdata)
291 {
292 int k;
293 float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
294 float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
295 float ftmp, ftmp2;
296
297 /* Form the polyphase signals*/
298 for (k=0;k<FRAMESAMPLES_HALF;k++) {
299 tempin_ch1[k]=InLP[k]+InHP[k]; /* Construct a new upper channel signal*/
300 tempin_ch2[k]=InLP[k]-InHP[k]; /* Construct a new lower channel signal*/
301 }
302
303
304 /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
305 that were used as a lower channel at the encoding side. So at the decoder, the
306 corresponding all-pass filter factors for each channel are swapped.*/
307 WebRtcIsac_AllPassFilter2Float(tempin_ch1, WebRtcIsac_kLowerApFactorsFloat,
308 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_float);
309
310 /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
311 at the decoder are swapped from the ones at the encoder, the 'upper' channel
312 all-pass filter factors (WebRtcIsac_kUpperApFactorsFloat) are used to filter this new
313 lower channel signal */
314 WebRtcIsac_AllPassFilter2Float(tempin_ch2, WebRtcIsac_kUpperApFactorsFloat,
315 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_float);
316
317
318 /* Merge outputs to form the full length output signal.*/
319 for (k=0;k<FRAMESAMPLES_HALF;k++) {
320 Out[2*k]=tempin_ch2[k];
321 Out[2*k+1]=tempin_ch1[k];
322 }
323
324
325 /* High pass filter */
326
327 for (k=0;k<FRAMESAMPLES;k++) {
328 ftmp2 = Out[k] + kHpStCoefOut1Float[2] * postfiltdata->HPstates1_float[0] +
329 kHpStCoefOut1Float[3] * postfiltdata->HPstates1_float[1];
330 ftmp = Out[k] - kHpStCoefOut1Float[0] * postfiltdata->HPstates1_float[0] -
331 kHpStCoefOut1Float[1] * postfiltdata->HPstates1_float[1];
332 postfiltdata->HPstates1_float[1] = postfiltdata->HPstates1_float[0];
333 postfiltdata->HPstates1_float[0] = ftmp;
334 Out[k] = ftmp2;
335 }
336
337 for (k=0;k<FRAMESAMPLES;k++) {
338 ftmp2 = Out[k] + kHpStCoefOut2Float[2] * postfiltdata->HPstates2_float[0] +
339 kHpStCoefOut2Float[3] * postfiltdata->HPstates2_float[1];
340 ftmp = Out[k] - kHpStCoefOut2Float[0] * postfiltdata->HPstates2_float[0] -
341 kHpStCoefOut2Float[1] * postfiltdata->HPstates2_float[1];
342 postfiltdata->HPstates2_float[1] = postfiltdata->HPstates2_float[0];
343 postfiltdata->HPstates2_float[0] = ftmp;
344 Out[k] = ftmp2;
345 }
346 }
347