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 * This file contains the splitting filter functions.
13 *
14 */
15
16 #include "rtc_base/checks.h"
17 #include "common_audio/signal_processing/include/signal_processing_library.h"
18
19 // Maximum number of samples in a low/high-band frame.
20 enum
21 {
22 kMaxBandFrameLength = 320 // 10 ms at 64 kHz.
23 };
24
25 // QMF filter coefficients in Q16.
26 static const uint16_t WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261};
27 static const uint16_t WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010};
28
29 ///////////////////////////////////////////////////////////////////////////////////////////////
30 // WebRtcSpl_AllPassQMF(...)
31 //
32 // Allpass filter used by the analysis and synthesis parts of the QMF filter.
33 //
34 // Input:
35 // - in_data : Input data sequence (Q10)
36 // - data_length : Length of data sequence (>2)
37 // - filter_coefficients : Filter coefficients (length 3, Q16)
38 //
39 // Input & Output:
40 // - filter_state : Filter state (length 6, Q10).
41 //
42 // Output:
43 // - out_data : Output data sequence (Q10), length equal to
44 // |data_length|
45 //
46
WebRtcSpl_AllPassQMF(int32_t * in_data,size_t data_length,int32_t * out_data,const uint16_t * filter_coefficients,int32_t * filter_state)47 static void WebRtcSpl_AllPassQMF(int32_t* in_data,
48 size_t data_length,
49 int32_t* out_data,
50 const uint16_t* filter_coefficients,
51 int32_t* filter_state)
52 {
53 // The procedure is to filter the input with three first order all pass filters
54 // (cascade operations).
55 //
56 // a_3 + q^-1 a_2 + q^-1 a_1 + q^-1
57 // y[n] = ----------- ----------- ----------- x[n]
58 // 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1
59 //
60 // The input vector |filter_coefficients| includes these three filter coefficients.
61 // The filter state contains the in_data state, in_data[-1], followed by
62 // the out_data state, out_data[-1]. This is repeated for each cascade.
63 // The first cascade filter will filter the |in_data| and store the output in
64 // |out_data|. The second will the take the |out_data| as input and make an
65 // intermediate storage in |in_data|, to save memory. The third, and final, cascade
66 // filter operation takes the |in_data| (which is the output from the previous cascade
67 // filter) and store the output in |out_data|.
68 // Note that the input vector values are changed during the process.
69 size_t k;
70 int32_t diff;
71 // First all-pass cascade; filter from in_data to out_data.
72
73 // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at
74 // vector position n. Then the final output will be y[n] = y_3[n]
75
76 // First loop, use the states stored in memory.
77 // "diff" should be safe from wrap around since max values are 2^25
78 // diff = (x[0] - y_1[-1])
79 diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[1]);
80 // y_1[0] = x[-1] + a_1 * (x[0] - y_1[-1])
81 out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]);
82
83 // For the remaining loops, use previous values.
84 for (k = 1; k < data_length; k++)
85 {
86 // diff = (x[n] - y_1[n-1])
87 diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]);
88 // y_1[n] = x[n-1] + a_1 * (x[n] - y_1[n-1])
89 out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]);
90 }
91
92 // Update states.
93 filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time
94 filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time
95
96 // Second all-pass cascade; filter from out_data to in_data.
97 // diff = (y_1[0] - y_2[-1])
98 diff = WebRtcSpl_SubSatW32(out_data[0], filter_state[3]);
99 // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1])
100 in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]);
101 for (k = 1; k < data_length; k++)
102 {
103 // diff = (y_1[n] - y_2[n-1])
104 diff = WebRtcSpl_SubSatW32(out_data[k], in_data[k - 1]);
105 // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1])
106 in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]);
107 }
108
109 filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time
110 filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time
111
112 // Third all-pass cascade; filter from in_data to out_data.
113 // diff = (y_2[0] - y[-1])
114 diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[5]);
115 // y[0] = y_2[-1] + a_3 * (y_2[0] - y[-1])
116 out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]);
117 for (k = 1; k < data_length; k++)
118 {
119 // diff = (y_2[n] - y[n-1])
120 diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]);
121 // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1])
122 out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]);
123 }
124 filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time
125 filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time
126 }
127
WebRtcSpl_AnalysisQMF(const int16_t * in_data,size_t in_data_length,int16_t * low_band,int16_t * high_band,int32_t * filter_state1,int32_t * filter_state2)128 void WebRtcSpl_AnalysisQMF(const int16_t* in_data, size_t in_data_length,
129 int16_t* low_band, int16_t* high_band,
130 int32_t* filter_state1, int32_t* filter_state2)
131 {
132 size_t i;
133 int16_t k;
134 int32_t tmp;
135 int32_t half_in1[kMaxBandFrameLength];
136 int32_t half_in2[kMaxBandFrameLength];
137 int32_t filter1[kMaxBandFrameLength];
138 int32_t filter2[kMaxBandFrameLength];
139 const size_t band_length = in_data_length / 2;
140 RTC_DCHECK_EQ(0, in_data_length % 2);
141 RTC_DCHECK_LE(band_length, kMaxBandFrameLength);
142
143 // Split even and odd samples. Also shift them to Q10.
144 for (i = 0, k = 0; i < band_length; i++, k += 2)
145 {
146 half_in2[i] = ((int32_t)in_data[k]) * (1 << 10);
147 half_in1[i] = ((int32_t)in_data[k + 1]) * (1 << 10);
148 }
149
150 // All pass filter even and odd samples, independently.
151 WebRtcSpl_AllPassQMF(half_in1, band_length, filter1,
152 WebRtcSpl_kAllPassFilter1, filter_state1);
153 WebRtcSpl_AllPassQMF(half_in2, band_length, filter2,
154 WebRtcSpl_kAllPassFilter2, filter_state2);
155
156 // Take the sum and difference of filtered version of odd and even
157 // branches to get upper & lower band.
158 for (i = 0; i < band_length; i++)
159 {
160 tmp = (filter1[i] + filter2[i] + 1024) >> 11;
161 low_band[i] = WebRtcSpl_SatW32ToW16(tmp);
162
163 tmp = (filter1[i] - filter2[i] + 1024) >> 11;
164 high_band[i] = WebRtcSpl_SatW32ToW16(tmp);
165 }
166 }
167
WebRtcSpl_SynthesisQMF(const int16_t * low_band,const int16_t * high_band,size_t band_length,int16_t * out_data,int32_t * filter_state1,int32_t * filter_state2)168 void WebRtcSpl_SynthesisQMF(const int16_t* low_band, const int16_t* high_band,
169 size_t band_length, int16_t* out_data,
170 int32_t* filter_state1, int32_t* filter_state2)
171 {
172 int32_t tmp;
173 int32_t half_in1[kMaxBandFrameLength];
174 int32_t half_in2[kMaxBandFrameLength];
175 int32_t filter1[kMaxBandFrameLength];
176 int32_t filter2[kMaxBandFrameLength];
177 size_t i;
178 int16_t k;
179 RTC_DCHECK_LE(band_length, kMaxBandFrameLength);
180
181 // Obtain the sum and difference channels out of upper and lower-band channels.
182 // Also shift to Q10 domain.
183 for (i = 0; i < band_length; i++)
184 {
185 tmp = (int32_t)low_band[i] + (int32_t)high_band[i];
186 half_in1[i] = tmp * (1 << 10);
187 tmp = (int32_t)low_band[i] - (int32_t)high_band[i];
188 half_in2[i] = tmp * (1 << 10);
189 }
190
191 // all-pass filter the sum and difference channels
192 WebRtcSpl_AllPassQMF(half_in1, band_length, filter1,
193 WebRtcSpl_kAllPassFilter2, filter_state1);
194 WebRtcSpl_AllPassQMF(half_in2, band_length, filter2,
195 WebRtcSpl_kAllPassFilter1, filter_state2);
196
197 // The filtered signals are even and odd samples of the output. Combine
198 // them. The signals are Q10 should shift them back to Q0 and take care of
199 // saturation.
200 for (i = 0, k = 0; i < band_length; i++)
201 {
202 tmp = (filter2[i] + 512) >> 10;
203 out_data[k++] = WebRtcSpl_SatW32ToW16(tmp);
204
205 tmp = (filter1[i] + 512) >> 10;
206 out_data[k++] = WebRtcSpl_SatW32ToW16(tmp);
207 }
208
209 }
210