OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 return aRe * bIm + aIm * bRe; | 144 return aRe * bIm + aIm * bRe; |
145 } | 145 } |
146 | 146 |
147 static int CmpFloat(const void* a, const void* b) { | 147 static int CmpFloat(const void* a, const void* b) { |
148 const float* da = (const float*)a; | 148 const float* da = (const float*)a; |
149 const float* db = (const float*)b; | 149 const float* db = (const float*)b; |
150 | 150 |
151 return (*da > *db) - (*da < *db); | 151 return (*da > *db) - (*da < *db); |
152 } | 152 } |
153 | 153 |
154 static void FilterFar(int num_partitions, | 154 static void FilterFar( |
155 int x_fft_buffer_block_pos, | 155 int num_partitions, |
156 float x_fft_buffer[2][kExtendedNumPartitions * PART_LEN1], | 156 int x_fft_buf_block_pos, |
157 float h_fft_buffer[2][kExtendedNumPartitions * PART_LEN1], | 157 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
158 float y_fft[2][PART_LEN1]) { | 158 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
| 159 float y_fft[2][PART_LEN1]) { |
159 int i; | 160 int i; |
160 for (i = 0; i < num_partitions; i++) { | 161 for (i = 0; i < num_partitions; i++) { |
161 int j; | 162 int j; |
162 int x_pos = (i + x_fft_buffer_block_pos) * PART_LEN1; | 163 int xPos = (i + x_fft_buf_block_pos) * PART_LEN1; |
163 int pos = i * PART_LEN1; | 164 int pos = i * PART_LEN1; |
164 // Check for wrapped buffer. | 165 // Check for wrap |
165 if (i + x_fft_buffer_block_pos >= num_partitions) { | 166 if (i + x_fft_buf_block_pos >= num_partitions) { |
166 x_pos -= num_partitions * (PART_LEN1); | 167 xPos -= num_partitions * (PART_LEN1); |
167 } | 168 } |
168 | 169 |
169 for (j = 0; j < PART_LEN1; j++) { | 170 for (j = 0; j < PART_LEN1; j++) { |
170 y_fft[0][j] += MulRe(x_fft_buffer[0][x_pos + j], | 171 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], |
171 x_fft_buffer[1][x_pos + j], | 172 x_fft_buf[1][xPos + j], |
172 h_fft_buffer[0][pos + j], | 173 h_fft_buf[0][pos + j], |
173 h_fft_buffer[1][pos + j]); | 174 h_fft_buf[1][pos + j]); |
174 y_fft[1][j] += MulIm(x_fft_buffer[0][x_pos + j], | 175 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], |
175 x_fft_buffer[1][x_pos + j], | 176 x_fft_buf[1][xPos + j], |
176 h_fft_buffer[0][pos + j], | 177 h_fft_buf[0][pos + j], |
177 h_fft_buffer[1][pos + j]); | 178 h_fft_buf[1][pos + j]); |
178 } | 179 } |
179 } | 180 } |
180 } | 181 } |
181 | 182 |
182 static void ScaleErrorSignal(int extended_filter_enabled, | 183 static void ScaleErrorSignal(int extended_filter_enabled, |
183 float normal_mu, | 184 float normal_mu, |
184 float normal_error_threshold, | 185 float normal_error_threshold, |
185 float *x_pow, | 186 float x_pow[PART_LEN1], |
186 float ef[2][PART_LEN1]) { | 187 float ef[2][PART_LEN1]) { |
187 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; | 188 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; |
188 const float error_threshold = extended_filter_enabled | 189 const float error_threshold = extended_filter_enabled |
189 ? kExtendedErrorThreshold | 190 ? kExtendedErrorThreshold |
190 : normal_error_threshold; | 191 : normal_error_threshold; |
191 int i; | 192 int i; |
192 float abs_ef; | 193 float abs_ef; |
193 for (i = 0; i < (PART_LEN1); i++) { | 194 for (i = 0; i < (PART_LEN1); i++) { |
194 ef[0][i] /= (x_pow[i] + 1e-10f); | 195 ef[0][i] /= (x_pow[i] + 1e-10f); |
195 ef[1][i] /= (x_pow[i] + 1e-10f); | 196 ef[1][i] /= (x_pow[i] + 1e-10f); |
196 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); | 197 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); |
197 | 198 |
198 if (abs_ef > error_threshold) { | 199 if (abs_ef > error_threshold) { |
199 abs_ef = error_threshold / (abs_ef + 1e-10f); | 200 abs_ef = error_threshold / (abs_ef + 1e-10f); |
200 ef[0][i] *= abs_ef; | 201 ef[0][i] *= abs_ef; |
201 ef[1][i] *= abs_ef; | 202 ef[1][i] *= abs_ef; |
202 } | 203 } |
203 | 204 |
204 // Stepsize factor | 205 // Stepsize factor |
205 ef[0][i] *= mu; | 206 ef[0][i] *= mu; |
206 ef[1][i] *= mu; | 207 ef[1][i] *= mu; |
207 } | 208 } |
208 } | 209 } |
209 | 210 |
210 // Time-unconstrined filter adaptation. | |
211 // TODO(andrew): consider for a low-complexity mode. | |
212 // static void FilterAdaptationUnconstrained(AecCore* aec, float *fft, | |
213 // float ef[2][PART_LEN1]) { | |
214 // int i, j; | |
215 // for (i = 0; i < aec->num_partitions; i++) { | |
216 // int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1); | |
217 // int pos; | |
218 // // Check for wrap | |
219 // if (i + aec->xfBufBlockPos >= aec->num_partitions) { | |
220 // xPos -= aec->num_partitions * PART_LEN1; | |
221 // } | |
222 // | |
223 // pos = i * PART_LEN1; | |
224 // | |
225 // for (j = 0; j < PART_LEN1; j++) { | |
226 // aec->wfBuf[0][pos + j] += MulRe(aec->xfBuf[0][xPos + j], | |
227 // -aec->xfBuf[1][xPos + j], | |
228 // ef[0][j], ef[1][j]); | |
229 // aec->wfBuf[1][pos + j] += MulIm(aec->xfBuf[0][xPos + j], | |
230 // -aec->xfBuf[1][xPos + j], | |
231 // ef[0][j], ef[1][j]); | |
232 // } | |
233 // } | |
234 //} | |
235 | 211 |
236 static void FilterAdaptation(AecCore* aec, float* fft, float ef[2][PART_LEN1]) { | 212 static void FilterAdaptation( |
| 213 int num_partitions, |
| 214 int x_fft_buf_block_pos, |
| 215 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
| 216 float e_fft[2][PART_LEN1], |
| 217 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) { |
237 int i, j; | 218 int i, j; |
238 for (i = 0; i < aec->num_partitions; i++) { | 219 float fft[PART_LEN2]; |
239 int xPos = (i + aec->xfBufBlockPos) * (PART_LEN1); | 220 for (i = 0; i < num_partitions; i++) { |
| 221 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1); |
240 int pos; | 222 int pos; |
241 // Check for wrap | 223 // Check for wrap |
242 if (i + aec->xfBufBlockPos >= aec->num_partitions) { | 224 if (i + x_fft_buf_block_pos >= num_partitions) { |
243 xPos -= aec->num_partitions * PART_LEN1; | 225 xPos -= num_partitions * PART_LEN1; |
244 } | 226 } |
245 | 227 |
246 pos = i * PART_LEN1; | 228 pos = i * PART_LEN1; |
247 | 229 |
248 for (j = 0; j < PART_LEN; j++) { | 230 for (j = 0; j < PART_LEN; j++) { |
249 | 231 |
250 fft[2 * j] = MulRe(aec->xfBuf[0][xPos + j], | 232 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], |
251 -aec->xfBuf[1][xPos + j], | 233 -x_fft_buf[1][xPos + j], |
252 ef[0][j], | 234 e_fft[0][j], |
253 ef[1][j]); | 235 e_fft[1][j]); |
254 fft[2 * j + 1] = MulIm(aec->xfBuf[0][xPos + j], | 236 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j], |
255 -aec->xfBuf[1][xPos + j], | 237 -x_fft_buf[1][xPos + j], |
256 ef[0][j], | 238 e_fft[0][j], |
257 ef[1][j]); | 239 e_fft[1][j]); |
258 } | 240 } |
259 fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN], | 241 fft[1] = MulRe(x_fft_buf[0][xPos + PART_LEN], |
260 -aec->xfBuf[1][xPos + PART_LEN], | 242 -x_fft_buf[1][xPos + PART_LEN], |
261 ef[0][PART_LEN], | 243 e_fft[0][PART_LEN], |
262 ef[1][PART_LEN]); | 244 e_fft[1][PART_LEN]); |
263 | 245 |
264 aec_rdft_inverse_128(fft); | 246 aec_rdft_inverse_128(fft); |
265 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); | 247 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); |
266 | 248 |
267 // fft scaling | 249 // fft scaling |
268 { | 250 { |
269 float scale = 2.0f / PART_LEN2; | 251 float scale = 2.0f / PART_LEN2; |
270 for (j = 0; j < PART_LEN; j++) { | 252 for (j = 0; j < PART_LEN; j++) { |
271 fft[j] *= scale; | 253 fft[j] *= scale; |
272 } | 254 } |
273 } | 255 } |
274 aec_rdft_forward_128(fft); | 256 aec_rdft_forward_128(fft); |
275 | 257 |
276 aec->wfBuf[0][pos] += fft[0]; | 258 h_fft_buf[0][pos] += fft[0]; |
277 aec->wfBuf[0][pos + PART_LEN] += fft[1]; | 259 h_fft_buf[0][pos + PART_LEN] += fft[1]; |
278 | 260 |
279 for (j = 1; j < PART_LEN; j++) { | 261 for (j = 1; j < PART_LEN; j++) { |
280 aec->wfBuf[0][pos + j] += fft[2 * j]; | 262 h_fft_buf[0][pos + j] += fft[2 * j]; |
281 aec->wfBuf[1][pos + j] += fft[2 * j + 1]; | 263 h_fft_buf[1][pos + j] += fft[2 * j + 1]; |
282 } | 264 } |
283 } | 265 } |
284 } | 266 } |
285 | 267 |
286 static void OverdriveAndSuppress(AecCore* aec, | 268 static void OverdriveAndSuppress(AecCore* aec, |
287 float hNl[PART_LEN1], | 269 float hNl[PART_LEN1], |
288 const float hNlFb, | 270 const float hNlFb, |
289 float efw[2][PART_LEN1]) { | 271 float efw[2][PART_LEN1]) { |
290 int i; | 272 int i; |
291 for (i = 0; i < PART_LEN1; i++) { | 273 for (i = 0; i < PART_LEN1; i++) { |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 self->num_delay_values; | 820 self->num_delay_values; |
839 } | 821 } |
840 | 822 |
841 // Reset histogram. | 823 // Reset histogram. |
842 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); | 824 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); |
843 self->num_delay_values = 0; | 825 self->num_delay_values = 0; |
844 | 826 |
845 return; | 827 return; |
846 } | 828 } |
847 | 829 |
848 static void FrequencyToTime(float freq_data[2][PART_LEN1], | 830 static void InverseFft(float freq_data[2][PART_LEN1], |
849 float time_data[PART_LEN2]) { | 831 float time_data[PART_LEN2]) { |
850 int i; | 832 int i; |
851 time_data[0] = freq_data[0][0]; | 833 const float scale = 1.0f / PART_LEN2; |
852 time_data[1] = freq_data[0][PART_LEN]; | 834 time_data[0] = freq_data[0][0] * scale; |
| 835 time_data[1] = freq_data[0][PART_LEN] * scale; |
853 for (i = 1; i < PART_LEN; i++) { | 836 for (i = 1; i < PART_LEN; i++) { |
854 time_data[2 * i] = freq_data[0][i]; | 837 time_data[2 * i] = freq_data[0][i] * scale; |
855 time_data[2 * i + 1] = freq_data[1][i]; | 838 time_data[2 * i + 1] = freq_data[1][i] * scale; |
856 } | 839 } |
857 aec_rdft_inverse_128(time_data); | 840 aec_rdft_inverse_128(time_data); |
858 } | 841 } |
859 | 842 |
860 | 843 |
861 static void TimeToFrequency(float time_data[PART_LEN2], | 844 static void Fft(float time_data[PART_LEN2], |
862 float freq_data[2][PART_LEN1], | 845 float freq_data[2][PART_LEN1]) { |
863 int window) { | 846 int i; |
864 int i = 0; | 847 aec_rdft_forward_128(time_data); |
865 | 848 |
866 // TODO(bjornv): Should we have a different function/wrapper for windowed FFT? | 849 // Reorder fft output data. |
867 if (window) { | |
868 for (i = 0; i < PART_LEN; i++) { | |
869 time_data[i] *= WebRtcAec_sqrtHanning[i]; | |
870 time_data[PART_LEN + i] *= WebRtcAec_sqrtHanning[PART_LEN - i]; | |
871 } | |
872 } | |
873 | |
874 aec_rdft_forward_128(time_data); | |
875 // Reorder. | |
876 freq_data[1][0] = 0; | 850 freq_data[1][0] = 0; |
877 freq_data[1][PART_LEN] = 0; | 851 freq_data[1][PART_LEN] = 0; |
878 freq_data[0][0] = time_data[0]; | 852 freq_data[0][0] = time_data[0]; |
879 freq_data[0][PART_LEN] = time_data[1]; | 853 freq_data[0][PART_LEN] = time_data[1]; |
880 for (i = 1; i < PART_LEN; i++) { | 854 for (i = 1; i < PART_LEN; i++) { |
881 freq_data[0][i] = time_data[2 * i]; | 855 freq_data[0][i] = time_data[2 * i]; |
882 freq_data[1][i] = time_data[2 * i + 1]; | 856 freq_data[1][i] = time_data[2 * i + 1]; |
883 } | 857 } |
884 } | 858 } |
885 | 859 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); | 930 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); |
957 delay_quality = (delay_quality > kDelayQualityThresholdMax ? | 931 delay_quality = (delay_quality > kDelayQualityThresholdMax ? |
958 kDelayQualityThresholdMax : delay_quality); | 932 kDelayQualityThresholdMax : delay_quality); |
959 self->delay_quality_threshold = | 933 self->delay_quality_threshold = |
960 (delay_quality > self->delay_quality_threshold ? delay_quality : | 934 (delay_quality > self->delay_quality_threshold ? delay_quality : |
961 self->delay_quality_threshold); | 935 self->delay_quality_threshold); |
962 } | 936 } |
963 return delay_correction; | 937 return delay_correction; |
964 } | 938 } |
965 | 939 |
966 static void EchoSubtraction(AecCore* aec, | 940 static void EchoSubtraction( |
967 float* nearend_ptr) { | 941 AecCore* aec, |
968 float yf[2][PART_LEN1]; | 942 int num_partitions, |
969 float fft[PART_LEN2]; | 943 int x_fft_buf_block_pos, |
970 float y[PART_LEN]; | 944 int metrics_mode, |
| 945 int extended_filter_enabled, |
| 946 float normal_mu, |
| 947 float normal_error_threshold, |
| 948 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
| 949 float* const y, |
| 950 float x_pow[PART_LEN1], |
| 951 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
| 952 PowerLevel* linout_level, |
| 953 float echo_subtractor_output[PART_LEN]) { |
| 954 float s_fft[2][PART_LEN1]; |
| 955 float e_extended[PART_LEN2]; |
| 956 float s_extended[PART_LEN2]; |
| 957 float *s; |
971 float e[PART_LEN]; | 958 float e[PART_LEN]; |
972 float ef[2][PART_LEN1]; | 959 float e_fft[2][PART_LEN1]; |
973 float scale; | |
974 int i; | 960 int i; |
975 memset(yf, 0, sizeof(yf)); | 961 memset(s_fft, 0, sizeof(s_fft)); |
976 | 962 |
977 // Produce frequency domain echo estimate. | 963 // Produce echo estimate s_fft. |
978 WebRtcAec_FilterFar(aec->num_partitions, | 964 WebRtcAec_FilterFar(num_partitions, |
979 aec->xfBufBlockPos, | 965 x_fft_buf_block_pos, |
980 aec->xfBuf, | 966 x_fft_buf, |
981 aec->wfBuf, | 967 h_fft_buf, |
982 yf); | 968 s_fft); |
983 | 969 |
984 // Inverse fft to obtain echo estimate and error. | 970 // Compute the time-domain echo estimate s. |
985 FrequencyToTime(yf, fft); | 971 InverseFft(s_fft, s_extended); |
986 | 972 s = &s_extended[PART_LEN]; |
987 // Extract the output signal and compute the time-domain error. | |
988 scale = 2.0f / PART_LEN2; | |
989 for (i = 0; i < PART_LEN; ++i) { | 973 for (i = 0; i < PART_LEN; ++i) { |
990 y[i] = fft[PART_LEN + i] * scale; // fft scaling. | 974 s[i] *= 2.0f; |
991 e[i] = nearend_ptr[i] - y[i]; | |
992 } | 975 } |
993 | 976 |
994 // Error fft | 977 // Compute the time-domain echo prediction error. |
995 memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN); | 978 for (i = 0; i < PART_LEN; ++i) { |
996 memset(fft, 0, sizeof(float) * PART_LEN); | 979 e[i] = y[i] - s[i]; |
997 memcpy(fft + PART_LEN, e, sizeof(float) * PART_LEN); | 980 } |
998 TimeToFrequency(fft, ef, 0); | 981 |
| 982 // Compute the frequency domain echo prediction error. |
| 983 memset(e_extended, 0, sizeof(float) * PART_LEN); |
| 984 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
| 985 Fft(e_extended, e_fft); |
999 | 986 |
1000 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, | 987 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, |
1001 &ef[0][0], | 988 &e_fft[0][0], |
1002 sizeof(ef[0][0]) * PART_LEN1 * 2); | 989 sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
1003 | 990 |
1004 if (aec->metricsMode == 1) { | 991 if (metrics_mode == 1) { |
1005 // Note that the first PART_LEN samples in fft (before transformation) are | 992 // Note that the first PART_LEN samples in fft (before transformation) are |
1006 // zero. Hence, the scaling by two in UpdateLevel() should not be | 993 // zero. Hence, the scaling by two in UpdateLevel() should not be |
1007 // performed. That scaling is taken care of in UpdateMetrics() instead. | 994 // performed. That scaling is taken care of in UpdateMetrics() instead. |
1008 UpdateLevel(&aec->linoutlevel, ef); | 995 UpdateLevel(linout_level, e_fft); |
1009 } | 996 } |
1010 | 997 |
1011 // Scale error signal inversely with far power. | 998 // Scale error signal inversely with far power. |
1012 WebRtcAec_ScaleErrorSignal(aec->extended_filter_enabled, | 999 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, |
1013 aec->normal_mu, | 1000 normal_mu, |
1014 aec->normal_error_threshold, | 1001 normal_error_threshold, |
1015 aec->xPow, | 1002 x_pow, |
1016 ef); | 1003 e_fft); |
1017 WebRtcAec_FilterAdaptation(aec, fft, ef); | 1004 WebRtcAec_FilterAdaptation(num_partitions, |
1018 | 1005 x_fft_buf_block_pos, |
1019 | 1006 x_fft_buf, |
1020 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, e, PART_LEN); | 1007 e_fft, |
| 1008 h_fft_buf); |
| 1009 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
1021 } | 1010 } |
1022 | 1011 |
1023 | 1012 |
1024 static void EchoSuppression(AecCore* aec, | 1013 static void EchoSuppression(AecCore* aec, |
1025 float* output, | 1014 float* output, |
1026 float* const* outputH) { | 1015 float* const* outputH) { |
1027 float efw[2][PART_LEN1], xfw[2][PART_LEN1]; | 1016 float efw[2][PART_LEN1], xfw[2][PART_LEN1]; |
1028 complex_t comfortNoiseHband[PART_LEN1]; | 1017 complex_t comfortNoiseHband[PART_LEN1]; |
1029 float fft[PART_LEN2]; | 1018 float fft[PART_LEN2]; |
1030 float scale, dtmp; | 1019 float scale, dtmp; |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 | 1256 |
1268 const float gPow[2] = {0.9f, 0.1f}; | 1257 const float gPow[2] = {0.9f, 0.1f}; |
1269 | 1258 |
1270 // Noise estimate constants. | 1259 // Noise estimate constants. |
1271 const int noiseInitBlocks = 500 * aec->mult; | 1260 const int noiseInitBlocks = 500 * aec->mult; |
1272 const float step = 0.1f; | 1261 const float step = 0.1f; |
1273 const float ramp = 1.0002f; | 1262 const float ramp = 1.0002f; |
1274 const float gInitNoise[2] = {0.999f, 0.001f}; | 1263 const float gInitNoise[2] = {0.999f, 0.001f}; |
1275 | 1264 |
1276 float nearend[PART_LEN]; | 1265 float nearend[PART_LEN]; |
| 1266 float echo_subtractor_output[PART_LEN]; |
1277 float* nearend_ptr = NULL; | 1267 float* nearend_ptr = NULL; |
1278 float output[PART_LEN]; | 1268 float output[PART_LEN]; |
1279 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1269 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1280 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1270 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
1281 float* xf_ptr = NULL; | 1271 float* xf_ptr = NULL; |
1282 | 1272 |
1283 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1273 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1284 outputH_ptr[i] = outputH[i]; | 1274 outputH_ptr[i] = outputH[i]; |
1285 } | 1275 } |
1286 | 1276 |
(...skipping 19 matching lines...) Expand all Loading... |
1306 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); | 1296 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); |
1307 } | 1297 } |
1308 #endif | 1298 #endif |
1309 | 1299 |
1310 // We should always have at least one element stored in |far_buf|. | 1300 // We should always have at least one element stored in |far_buf|. |
1311 assert(WebRtc_available_read(aec->far_buf) > 0); | 1301 assert(WebRtc_available_read(aec->far_buf) > 0); |
1312 WebRtc_ReadBuffer(aec->far_buf, (void**)&xf_ptr, &xf[0][0], 1); | 1302 WebRtc_ReadBuffer(aec->far_buf, (void**)&xf_ptr, &xf[0][0], 1); |
1313 | 1303 |
1314 // Near fft | 1304 // Near fft |
1315 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1305 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
1316 TimeToFrequency(fft, df, 0); | 1306 Fft(fft, df); |
1317 | 1307 |
1318 // Power smoothing | 1308 // Power smoothing |
1319 for (i = 0; i < PART_LEN1; i++) { | 1309 for (i = 0; i < PART_LEN1; i++) { |
1320 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + | 1310 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + |
1321 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); | 1311 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); |
1322 aec->xPow[i] = | 1312 aec->xPow[i] = |
1323 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; | 1313 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; |
1324 // Calculate absolute spectra | 1314 // Calculate absolute spectra |
1325 abs_far_spectrum[i] = sqrtf(far_spectrum); | 1315 abs_far_spectrum[i] = sqrtf(far_spectrum); |
1326 | 1316 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 | 1375 |
1386 // Buffer xf | 1376 // Buffer xf |
1387 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, | 1377 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, |
1388 xf_ptr, | 1378 xf_ptr, |
1389 sizeof(float) * PART_LEN1); | 1379 sizeof(float) * PART_LEN1); |
1390 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, | 1380 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, |
1391 &xf_ptr[PART_LEN1], | 1381 &xf_ptr[PART_LEN1], |
1392 sizeof(float) * PART_LEN1); | 1382 sizeof(float) * PART_LEN1); |
1393 | 1383 |
1394 // Perform echo subtraction. | 1384 // Perform echo subtraction. |
1395 EchoSubtraction(aec, nearend_ptr); | 1385 EchoSubtraction(aec, |
| 1386 aec->num_partitions, |
| 1387 aec->xfBufBlockPos, |
| 1388 aec->metricsMode, |
| 1389 aec->extended_filter_enabled, |
| 1390 aec->normal_mu, |
| 1391 aec->normal_error_threshold, |
| 1392 aec->xfBuf, |
| 1393 nearend_ptr, |
| 1394 aec->xPow, |
| 1395 aec->wfBuf, |
| 1396 &aec->linoutlevel, |
| 1397 echo_subtractor_output); |
| 1398 |
| 1399 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
1396 | 1400 |
1397 // Perform echo suppression. | 1401 // Perform echo suppression. |
| 1402 memcpy(aec->eBuf + PART_LEN, |
| 1403 echo_subtractor_output, |
| 1404 sizeof(float) * PART_LEN); |
1398 EchoSuppression(aec, output, outputH_ptr); | 1405 EchoSuppression(aec, output, outputH_ptr); |
1399 | 1406 |
1400 if (aec->metricsMode == 1) { | 1407 if (aec->metricsMode == 1) { |
1401 // Update power levels and echo metrics | 1408 // Update power levels and echo metrics |
1402 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); | 1409 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); |
1403 UpdateLevel(&aec->nearlevel, df); | 1410 UpdateLevel(&aec->nearlevel, df); |
1404 UpdateMetrics(aec); | 1411 UpdateMetrics(aec); |
1405 } | 1412 } |
1406 | 1413 |
1407 // Store the output block. | 1414 // Store the output block. |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1730 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { | 1737 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { |
1731 float fft[PART_LEN2]; | 1738 float fft[PART_LEN2]; |
1732 float xf[2][PART_LEN1]; | 1739 float xf[2][PART_LEN1]; |
1733 | 1740 |
1734 // Check if the buffer is full, and in that case flush the oldest data. | 1741 // Check if the buffer is full, and in that case flush the oldest data. |
1735 if (WebRtc_available_write(aec->far_buf) < 1) { | 1742 if (WebRtc_available_write(aec->far_buf) < 1) { |
1736 WebRtcAec_MoveFarReadPtr(aec, 1); | 1743 WebRtcAec_MoveFarReadPtr(aec, 1); |
1737 } | 1744 } |
1738 // Convert far-end partition to the frequency domain without windowing. | 1745 // Convert far-end partition to the frequency domain without windowing. |
1739 memcpy(fft, farend, sizeof(float) * PART_LEN2); | 1746 memcpy(fft, farend, sizeof(float) * PART_LEN2); |
1740 TimeToFrequency(fft, xf, 0); | 1747 Fft(fft, xf); |
1741 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); | 1748 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); |
1742 | 1749 |
1743 // Convert far-end partition to the frequency domain with windowing. | 1750 // Convert far-end partition to the frequency domain with windowing. |
1744 memcpy(fft, farend, sizeof(float) * PART_LEN2); | 1751 WindowData(fft, farend); |
1745 TimeToFrequency(fft, xf, 1); | 1752 Fft(fft, xf); |
1746 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); | 1753 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); |
1747 } | 1754 } |
1748 | 1755 |
1749 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { | 1756 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { |
1750 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements); | 1757 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements); |
1751 aec->system_delay -= elements_moved * PART_LEN; | 1758 aec->system_delay -= elements_moved * PART_LEN; |
1752 return elements_moved; | 1759 return elements_moved; |
1753 } | 1760 } |
1754 | 1761 |
1755 void WebRtcAec_ProcessFrames(AecCore* aec, | 1762 void WebRtcAec_ProcessFrames(AecCore* aec, |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1947 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1954 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1948 return self->extended_filter_enabled; | 1955 return self->extended_filter_enabled; |
1949 } | 1956 } |
1950 | 1957 |
1951 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1958 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
1952 | 1959 |
1953 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1960 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1954 assert(delay >= 0); | 1961 assert(delay >= 0); |
1955 self->system_delay = delay; | 1962 self->system_delay = delay; |
1956 } | 1963 } |
OLD | NEW |