OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 27 matching lines...) Expand all Loading... |
38 // - filter_coefficients : Filter coefficients (length 3, Q16) | 38 // - filter_coefficients : Filter coefficients (length 3, Q16) |
39 // | 39 // |
40 // Input & Output: | 40 // Input & Output: |
41 // - filter_state : Filter state (length 6, Q10). | 41 // - filter_state : Filter state (length 6, Q10). |
42 // | 42 // |
43 // Output: | 43 // Output: |
44 // - out_data : Output data sequence (Q10), length equal to | 44 // - out_data : Output data sequence (Q10), length equal to |
45 // |data_length| | 45 // |data_length| |
46 // | 46 // |
47 | 47 |
48 void WebRtcSpl_AllPassQMF(int32_t* in_data, int data_length, | 48 void WebRtcSpl_AllPassQMF(int32_t* in_data, size_t data_length, |
49 int32_t* out_data, const uint16_t* filter_coefficients
, | 49 int32_t* out_data, const uint16_t* filter_coefficients
, |
50 int32_t* filter_state) | 50 int32_t* filter_state) |
51 { | 51 { |
52 // The procedure is to filter the input with three first order all pass filt
ers | 52 // The procedure is to filter the input with three first order all pass filt
ers |
53 // (cascade operations). | 53 // (cascade operations). |
54 // | 54 // |
55 // a_3 + q^-1 a_2 + q^-1 a_1 + q^-1 | 55 // a_3 + q^-1 a_2 + q^-1 a_1 + q^-1 |
56 // y[n] = ----------- ----------- ----------- x[n] | 56 // y[n] = ----------- ----------- ----------- x[n] |
57 // 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1 | 57 // 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1 |
58 // | 58 // |
59 // The input vector |filter_coefficients| includes these three filter coeffi
cients. | 59 // The input vector |filter_coefficients| includes these three filter coeffi
cients. |
60 // The filter state contains the in_data state, in_data[-1], followed by | 60 // The filter state contains the in_data state, in_data[-1], followed by |
61 // the out_data state, out_data[-1]. This is repeated for each cascade. | 61 // the out_data state, out_data[-1]. This is repeated for each cascade. |
62 // The first cascade filter will filter the |in_data| and store the output i
n | 62 // The first cascade filter will filter the |in_data| and store the output i
n |
63 // |out_data|. The second will the take the |out_data| as input and make an | 63 // |out_data|. The second will the take the |out_data| as input and make an |
64 // intermediate storage in |in_data|, to save memory. The third, and final,
cascade | 64 // intermediate storage in |in_data|, to save memory. The third, and final,
cascade |
65 // filter operation takes the |in_data| (which is the output from the previo
us cascade | 65 // filter operation takes the |in_data| (which is the output from the previo
us cascade |
66 // filter) and store the output in |out_data|. | 66 // filter) and store the output in |out_data|. |
67 // Note that the input vector values are changed during the process. | 67 // Note that the input vector values are changed during the process. |
68 int k; | 68 size_t k; |
69 int32_t diff; | 69 int32_t diff; |
70 // First all-pass cascade; filter from in_data to out_data. | 70 // First all-pass cascade; filter from in_data to out_data. |
71 | 71 |
72 // Let y_i[n] indicate the output of cascade filter i (with filter coefficie
nt a_i) at | 72 // Let y_i[n] indicate the output of cascade filter i (with filter coefficie
nt a_i) at |
73 // vector position n. Then the final output will be y[n] = y_3[n] | 73 // vector position n. Then the final output will be y[n] = y_3[n] |
74 | 74 |
75 // First loop, use the states stored in memory. | 75 // First loop, use the states stored in memory. |
76 // "diff" should be safe from wrap around since max values are 2^25 | 76 // "diff" should be safe from wrap around since max values are 2^25 |
77 // diff = (x[0] - y_1[-1]) | 77 // diff = (x[0] - y_1[-1]) |
78 diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[1]); | 78 diff = WebRtcSpl_SubSatW32(in_data[0], filter_state[1]); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 { | 117 { |
118 // diff = (y_2[n] - y[n-1]) | 118 // diff = (y_2[n] - y[n-1]) |
119 diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); | 119 diff = WebRtcSpl_SubSatW32(in_data[k], out_data[k - 1]); |
120 // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1]) | 120 // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1]) |
121 out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_da
ta[k-1]); | 121 out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_da
ta[k-1]); |
122 } | 122 } |
123 filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] nex
t time | 123 filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] nex
t time |
124 filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next t
ime | 124 filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next t
ime |
125 } | 125 } |
126 | 126 |
127 void WebRtcSpl_AnalysisQMF(const int16_t* in_data, int in_data_length, | 127 void WebRtcSpl_AnalysisQMF(const int16_t* in_data, size_t in_data_length, |
128 int16_t* low_band, int16_t* high_band, | 128 int16_t* low_band, int16_t* high_band, |
129 int32_t* filter_state1, int32_t* filter_state2) | 129 int32_t* filter_state1, int32_t* filter_state2) |
130 { | 130 { |
131 int16_t i; | 131 size_t i; |
132 int16_t k; | 132 int16_t k; |
133 int32_t tmp; | 133 int32_t tmp; |
134 int32_t half_in1[kMaxBandFrameLength]; | 134 int32_t half_in1[kMaxBandFrameLength]; |
135 int32_t half_in2[kMaxBandFrameLength]; | 135 int32_t half_in2[kMaxBandFrameLength]; |
136 int32_t filter1[kMaxBandFrameLength]; | 136 int32_t filter1[kMaxBandFrameLength]; |
137 int32_t filter2[kMaxBandFrameLength]; | 137 int32_t filter2[kMaxBandFrameLength]; |
138 const int band_length = in_data_length / 2; | 138 const size_t band_length = in_data_length / 2; |
139 assert(in_data_length % 2 == 0); | 139 assert(in_data_length % 2 == 0); |
140 assert(band_length <= kMaxBandFrameLength); | 140 assert(band_length <= kMaxBandFrameLength); |
141 | 141 |
142 // Split even and odd samples. Also shift them to Q10. | 142 // Split even and odd samples. Also shift them to Q10. |
143 for (i = 0, k = 0; i < band_length; i++, k += 2) | 143 for (i = 0, k = 0; i < band_length; i++, k += 2) |
144 { | 144 { |
145 half_in2[i] = WEBRTC_SPL_LSHIFT_W32((int32_t)in_data[k], 10); | 145 half_in2[i] = WEBRTC_SPL_LSHIFT_W32((int32_t)in_data[k], 10); |
146 half_in1[i] = WEBRTC_SPL_LSHIFT_W32((int32_t)in_data[k + 1], 10); | 146 half_in1[i] = WEBRTC_SPL_LSHIFT_W32((int32_t)in_data[k + 1], 10); |
147 } | 147 } |
148 | 148 |
149 // All pass filter even and odd samples, independently. | 149 // All pass filter even and odd samples, independently. |
150 WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, | 150 WebRtcSpl_AllPassQMF(half_in1, band_length, filter1, |
151 WebRtcSpl_kAllPassFilter1, filter_state1); | 151 WebRtcSpl_kAllPassFilter1, filter_state1); |
152 WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, | 152 WebRtcSpl_AllPassQMF(half_in2, band_length, filter2, |
153 WebRtcSpl_kAllPassFilter2, filter_state2); | 153 WebRtcSpl_kAllPassFilter2, filter_state2); |
154 | 154 |
155 // Take the sum and difference of filtered version of odd and even | 155 // Take the sum and difference of filtered version of odd and even |
156 // branches to get upper & lower band. | 156 // branches to get upper & lower band. |
157 for (i = 0; i < band_length; i++) | 157 for (i = 0; i < band_length; i++) |
158 { | 158 { |
159 tmp = (filter1[i] + filter2[i] + 1024) >> 11; | 159 tmp = (filter1[i] + filter2[i] + 1024) >> 11; |
160 low_band[i] = WebRtcSpl_SatW32ToW16(tmp); | 160 low_band[i] = WebRtcSpl_SatW32ToW16(tmp); |
161 | 161 |
162 tmp = (filter1[i] - filter2[i] + 1024) >> 11; | 162 tmp = (filter1[i] - filter2[i] + 1024) >> 11; |
163 high_band[i] = WebRtcSpl_SatW32ToW16(tmp); | 163 high_band[i] = WebRtcSpl_SatW32ToW16(tmp); |
164 } | 164 } |
165 } | 165 } |
166 | 166 |
167 void WebRtcSpl_SynthesisQMF(const int16_t* low_band, const int16_t* high_band, | 167 void WebRtcSpl_SynthesisQMF(const int16_t* low_band, const int16_t* high_band, |
168 int band_length, int16_t* out_data, | 168 size_t band_length, int16_t* out_data, |
169 int32_t* filter_state1, int32_t* filter_state2) | 169 int32_t* filter_state1, int32_t* filter_state2) |
170 { | 170 { |
171 int32_t tmp; | 171 int32_t tmp; |
172 int32_t half_in1[kMaxBandFrameLength]; | 172 int32_t half_in1[kMaxBandFrameLength]; |
173 int32_t half_in2[kMaxBandFrameLength]; | 173 int32_t half_in2[kMaxBandFrameLength]; |
174 int32_t filter1[kMaxBandFrameLength]; | 174 int32_t filter1[kMaxBandFrameLength]; |
175 int32_t filter2[kMaxBandFrameLength]; | 175 int32_t filter2[kMaxBandFrameLength]; |
176 int16_t i; | 176 size_t i; |
177 int16_t k; | 177 int16_t k; |
178 assert(band_length <= kMaxBandFrameLength); | 178 assert(band_length <= kMaxBandFrameLength); |
179 | 179 |
180 // Obtain the sum and difference channels out of upper and lower-band channe
ls. | 180 // Obtain the sum and difference channels out of upper and lower-band channe
ls. |
181 // Also shift to Q10 domain. | 181 // Also shift to Q10 domain. |
182 for (i = 0; i < band_length; i++) | 182 for (i = 0; i < band_length; i++) |
183 { | 183 { |
184 tmp = (int32_t)low_band[i] + (int32_t)high_band[i]; | 184 tmp = (int32_t)low_band[i] + (int32_t)high_band[i]; |
185 half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); | 185 half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); |
186 tmp = (int32_t)low_band[i] - (int32_t)high_band[i]; | 186 tmp = (int32_t)low_band[i] - (int32_t)high_band[i]; |
(...skipping 12 matching lines...) Expand all Loading... |
199 for (i = 0, k = 0; i < band_length; i++) | 199 for (i = 0, k = 0; i < band_length; i++) |
200 { | 200 { |
201 tmp = (filter2[i] + 512) >> 10; | 201 tmp = (filter2[i] + 512) >> 10; |
202 out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); | 202 out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); |
203 | 203 |
204 tmp = (filter1[i] + 512) >> 10; | 204 tmp = (filter1[i] + 512) >> 10; |
205 out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); | 205 out_data[k++] = WebRtcSpl_SatW32ToW16(tmp); |
206 } | 206 } |
207 | 207 |
208 } | 208 } |
OLD | NEW |