Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(924)

Side by Side Diff: webrtc/modules/audio_processing/aec/aec_core.cc

Issue 2319693003: Refactoring of the farend buffering scheme inside the AEC (Closed)
Patch Set: Rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 case DelaySource::kDelayAgnostic: 59 case DelaySource::kDelayAgnostic:
60 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.AecDelayAdjustmentMsAgnosticValue", 60 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.AecDelayAdjustmentMsAgnosticValue",
61 moved_ms, kMinDelayLogValue, kMaxDelayLogValue, 61 moved_ms, kMinDelayLogValue, kMaxDelayLogValue,
62 kNumDelayLogBuckets); 62 kNumDelayLogBuckets);
63 return; 63 return;
64 } 64 }
65 } 65 }
66 } // namespace 66 } // namespace
67 67
68 // Buffer size (samples) 68 // Buffer size (samples)
69 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. 69 static const size_t kBufferSizeBlocks = 250; // 1 second of audio in 16 kHz.
70 70
71 // Metrics 71 // Metrics
72 static const size_t kSubCountLen = 4; 72 static const size_t kSubCountLen = 4;
73 static const size_t kCountLen = 50; 73 static const size_t kCountLen = 50;
74 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. 74 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz.
75 75
76 // Divergence metric is based on audio level, which gets updated every 76 // Divergence metric is based on audio level, which gets updated every
77 // |kSubCountLen + 1| * PART_LEN samples. Divergence metric takes the statistics 77 // |kSubCountLen + 1| * PART_LEN samples. Divergence metric takes the statistics
78 // of |kDivergentFilterFractionAggregationWindowSize| audio levels. The 78 // of |kDivergentFilterFractionAggregationWindowSize| audio levels. The
79 // following value corresponds to 1 second at 16 kHz. 79 // following value corresponds to 1 second at 16 kHz.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 } 177 }
178 178
179 // TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a 179 // TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a
180 // window, of which the length is 1 unit longer than indicated. Remove "+1" when 180 // window, of which the length is 1 unit longer than indicated. Remove "+1" when
181 // the code is refactored. 181 // the code is refactored.
182 PowerLevel::PowerLevel() 182 PowerLevel::PowerLevel()
183 : framelevel(kSubCountLen + 1), 183 : framelevel(kSubCountLen + 1),
184 averagelevel(kCountLen + 1) { 184 averagelevel(kCountLen + 1) {
185 } 185 }
186 186
187 BlockBuffer::BlockBuffer() {
188 buffer_ = WebRtc_CreateBuffer(kBufferSizeBlocks, sizeof(float) * PART_LEN);
189 RTC_CHECK(buffer_);
190 ReInit();
191 }
192
193 BlockBuffer::~BlockBuffer() {
194 WebRtc_FreeBuffer(buffer_);
195 }
196
197 void BlockBuffer::ReInit() {
198 WebRtc_InitBuffer(buffer_);
199 }
200
201 void BlockBuffer::Insert(const float block[PART_LEN]) {
202 WebRtc_WriteBuffer(buffer_, block, 1);
203 }
204
205 void BlockBuffer::ExtractExtendedBlock(float extended_block[PART_LEN2]) {
206 float* block_ptr = NULL;
207 RTC_DCHECK_LT(0u, AvaliableSpace());
208
209 // Extract the previous block.
210 WebRtc_MoveReadPtr(buffer_, -1);
211 WebRtc_ReadBuffer(buffer_, reinterpret_cast<void**>(&block_ptr),
212 &extended_block[0], 1);
213 if (block_ptr != &extended_block[0]) {
214 memcpy(&extended_block[0], block_ptr, PART_LEN * sizeof(float));
215 }
216
217 // Extract the current block.
218 WebRtc_ReadBuffer(buffer_, reinterpret_cast<void**>(&block_ptr),
219 &extended_block[PART_LEN], 1);
220 if (block_ptr != &extended_block[PART_LEN]) {
221 memcpy(&extended_block[PART_LEN], block_ptr, PART_LEN * sizeof(float));
222 }
223 }
224
225 int BlockBuffer::AdjustSize(int buffer_size_decrease) {
226 return WebRtc_MoveReadPtr(buffer_, buffer_size_decrease);
227 }
228
229 size_t BlockBuffer::Size() {
230 return static_cast<int>(WebRtc_available_read(buffer_));
231 }
232
233 size_t BlockBuffer::AvaliableSpace() {
234 return WebRtc_available_write(buffer_);
235 }
236
187 DivergentFilterFraction::DivergentFilterFraction() 237 DivergentFilterFraction::DivergentFilterFraction()
188 : count_(0), 238 : count_(0),
189 occurrence_(0), 239 occurrence_(0),
190 fraction_(-1.0) { 240 fraction_(-1.0) {
191 } 241 }
192 242
193 void DivergentFilterFraction::Reset() { 243 void DivergentFilterFraction::Reset() {
194 Clear(); 244 Clear();
195 fraction_ = -1.0; 245 fraction_ = -1.0;
196 } 246 }
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 self->delay_quality_threshold)) { 900 self->delay_quality_threshold)) {
851 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); 901 int delay = last_delay - WebRtc_lookahead(self->delay_estimator);
852 // Allow for a slack in the actual delay, defined by a |lower_bound| and an 902 // Allow for a slack in the actual delay, defined by a |lower_bound| and an
853 // |upper_bound|. The adaptive echo cancellation filter is currently 903 // |upper_bound|. The adaptive echo cancellation filter is currently
854 // |num_partitions| (of 64 samples) long. If the delay estimate is negative 904 // |num_partitions| (of 64 samples) long. If the delay estimate is negative
855 // or at least 3/4 of the filter length we open up for correction. 905 // or at least 3/4 of the filter length we open up for correction.
856 const int lower_bound = 0; 906 const int lower_bound = 0;
857 const int upper_bound = self->num_partitions * 3 / 4; 907 const int upper_bound = self->num_partitions * 3 / 4;
858 const int do_correction = delay <= lower_bound || delay > upper_bound; 908 const int do_correction = delay <= lower_bound || delay > upper_bound;
859 if (do_correction == 1) { 909 if (do_correction == 1) {
860 int available_read = 910 int available_read = self->farend_block_buffer_.Size();
861 static_cast<int>(WebRtc_available_read(self->far_time_buf));
862 // With |shift_offset| we gradually rely on the delay estimates. For 911 // With |shift_offset| we gradually rely on the delay estimates. For
863 // positive delays we reduce the correction by |shift_offset| to lower the 912 // positive delays we reduce the correction by |shift_offset| to lower the
864 // risk of pushing the AEC into a non causal state. For negative delays 913 // risk of pushing the AEC into a non causal state. For negative delays
865 // we rely on the values up to a rounding error, hence compensate by 1 914 // we rely on the values up to a rounding error, hence compensate by 1
866 // element to make sure to push the delay into the causal region. 915 // element to make sure to push the delay into the causal region.
867 delay_correction = -delay; 916 delay_correction = -delay;
868 delay_correction += delay > self->shift_offset ? self->shift_offset : 1; 917 delay_correction += delay > self->shift_offset ? self->shift_offset : 1;
869 self->shift_offset--; 918 self->shift_offset--;
870 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); 919 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset);
871 if (delay_correction > available_read - self->mult - 1) { 920 if (delay_correction > available_read - self->mult - 1) {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 aec->overdrive_scaling = 1148 aec->overdrive_scaling =
1100 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive; 1149 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive;
1101 } 1150 }
1102 1151
1103 // Apply the overdrive. 1152 // Apply the overdrive.
1104 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl); 1153 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl);
1105 } 1154 }
1106 1155
1107 static void EchoSuppression(AecCore* aec, 1156 static void EchoSuppression(AecCore* aec,
1108 float* nearend_extended_block_lowest_band, 1157 float* nearend_extended_block_lowest_band,
1109 float farend[PART_LEN2], 1158 float farend_extended_block[PART_LEN2],
1110 float* echo_subtractor_output, 1159 float* echo_subtractor_output,
1111 float output[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) { 1160 float output[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
1112 float efw[2][PART_LEN1]; 1161 float efw[2][PART_LEN1];
1113 float xfw[2][PART_LEN1]; 1162 float xfw[2][PART_LEN1];
1114 float dfw[2][PART_LEN1]; 1163 float dfw[2][PART_LEN1];
1115 float comfortNoiseHband[2][PART_LEN1]; 1164 float comfortNoiseHband[2][PART_LEN1];
1116 float fft[PART_LEN2]; 1165 float fft[PART_LEN2];
1117 float nlpGainHband; 1166 float nlpGainHband;
1118 int i; 1167 int i;
1119 size_t j; 1168 size_t j;
(...skipping 18 matching lines...) Expand all
1138 StoreAsComplex(fft, dfw); 1187 StoreAsComplex(fft, dfw);
1139 1188
1140 // Windowed echo suppressor output ffts. 1189 // Windowed echo suppressor output ffts.
1141 WindowData(fft, aec->eBuf); 1190 WindowData(fft, aec->eBuf);
1142 aec_rdft_forward_128(fft); 1191 aec_rdft_forward_128(fft);
1143 StoreAsComplex(fft, efw); 1192 StoreAsComplex(fft, efw);
1144 1193
1145 // NLP 1194 // NLP
1146 1195
1147 // Convert far-end partition to the frequency domain with windowing. 1196 // Convert far-end partition to the frequency domain with windowing.
1148 WindowData(fft, farend); 1197 WindowData(fft, farend_extended_block);
1149 Fft(fft, xfw); 1198 Fft(fft, xfw);
1150 xfw_ptr = &xfw[0][0]; 1199 xfw_ptr = &xfw[0][0];
1151 1200
1152 // Buffer far. 1201 // Buffer far.
1153 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); 1202 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
1154 1203
1155 aec->delayEstCtr++; 1204 aec->delayEstCtr++;
1156 if (aec->delayEstCtr == delayEstInterval) { 1205 if (aec->delayEstCtr == delayEstInterval) {
1157 aec->delayEstCtr = 0; 1206 aec->delayEstCtr = 0;
1158 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); 1207 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 } 1281 }
1233 } 1282 }
1234 1283
1235 // Copy the current block to the old position. 1284 // Copy the current block to the old position.
1236 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); 1285 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);
1237 1286
1238 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, 1287 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf,
1239 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); 1288 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
1240 } 1289 }
1241 1290
1242 static void ProcessBlock(AecCore* aec, 1291 static void ProcessNearendBlock(
1243 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN], 1292 AecCore* aec,
1244 float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) { 1293 float farend_extended_block_lowest_band[PART_LEN2],
1294 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN],
1295 float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
1245 size_t i; 1296 size_t i;
1246 1297
1247 float fft[PART_LEN2]; 1298 float fft[PART_LEN2];
1248 float nearend_extended_block_lowest_band[PART_LEN2]; 1299 float nearend_extended_block_lowest_band[PART_LEN2];
1249 float x_fft[2][PART_LEN1]; 1300 float farend_fft[2][PART_LEN1];
1250 float df[2][PART_LEN1]; 1301 float nearend_fft[2][PART_LEN1];
1251 float far_spectrum = 0.0f; 1302 float far_spectrum = 0.0f;
1252 float near_spectrum = 0.0f; 1303 float near_spectrum = 0.0f;
1253 float abs_far_spectrum[PART_LEN1]; 1304 float abs_far_spectrum[PART_LEN1];
1254 float abs_near_spectrum[PART_LEN1]; 1305 float abs_near_spectrum[PART_LEN1];
1255 1306
1256 const float gPow[2] = {0.9f, 0.1f}; 1307 const float gPow[2] = {0.9f, 0.1f};
1257 1308
1258 // Noise estimate constants. 1309 // Noise estimate constants.
1259 const int noiseInitBlocks = 500 * aec->mult; 1310 const int noiseInitBlocks = 500 * aec->mult;
1260 const float step = 0.1f; 1311 const float step = 0.1f;
1261 const float ramp = 1.0002f; 1312 const float ramp = 1.0002f;
1262 const float gInitNoise[2] = {0.999f, 0.001f}; 1313 const float gInitNoise[2] = {0.999f, 0.001f};
1263 1314
1264 float farend[PART_LEN2];
1265 float* farend_ptr = NULL;
1266 float echo_subtractor_output[PART_LEN]; 1315 float echo_subtractor_output[PART_LEN];
1267 float* x_fft_ptr = NULL;
1268 1316
1269 // We should always have at least one element stored in |far_buf|. 1317 aec->data_dumper->DumpWav("aec_far", PART_LEN,
1270 assert(WebRtc_available_read(aec->far_time_buf) > 0); 1318 &farend_extended_block_lowest_band[PART_LEN],
1271 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr),
1272 farend, 1);
1273
1274 aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN],
1275 std::min(aec->sampFreq, 16000), 1); 1319 std::min(aec->sampFreq, 16000), 1);
1276 aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0], 1320 aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0],
1277 std::min(aec->sampFreq, 16000), 1); 1321 std::min(aec->sampFreq, 16000), 1);
1278 1322
1279 if (aec->metricsMode == 1) { 1323 if (aec->metricsMode == 1) {
1280 // Update power levels 1324 // Update power levels
1281 UpdateLevel(&aec->farlevel, 1325 UpdateLevel(
1282 CalculatePower(&farend_ptr[PART_LEN], PART_LEN)); 1326 &aec->farlevel,
1327 CalculatePower(&farend_extended_block_lowest_band[PART_LEN], PART_LEN));
1283 UpdateLevel(&aec->nearlevel, 1328 UpdateLevel(&aec->nearlevel,
1284 CalculatePower(&nearend_block[0][0], PART_LEN)); 1329 CalculatePower(&nearend_block[0][0], PART_LEN));
1285 } 1330 }
1286 1331
1287 // Convert far-end signal to the frequency domain. 1332 // Convert far-end signal to the frequency domain.
1288 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); 1333 memcpy(fft, farend_extended_block_lowest_band, sizeof(float) * PART_LEN2);
1289 Fft(fft, x_fft); 1334 Fft(fft, farend_fft);
1290 x_fft_ptr = &x_fft[0][0];
1291 1335
1292 // Form extended nearend frame. 1336 // Form extended nearend frame.
1293 memcpy(&nearend_extended_block_lowest_band[0], 1337 memcpy(&nearend_extended_block_lowest_band[0],
1294 &aec->previous_nearend_block[0][0], sizeof(float) * PART_LEN); 1338 &aec->previous_nearend_block[0][0], sizeof(float) * PART_LEN);
1295 memcpy(&nearend_extended_block_lowest_band[PART_LEN], &nearend_block[0][0], 1339 memcpy(&nearend_extended_block_lowest_band[PART_LEN], &nearend_block[0][0],
1296 sizeof(float) * PART_LEN); 1340 sizeof(float) * PART_LEN);
1297 1341
1298 // Near fft 1342 // Convert near-end signal to the frequency domain.
1299 memcpy(fft, nearend_extended_block_lowest_band, sizeof(float) * PART_LEN2); 1343 memcpy(fft, nearend_extended_block_lowest_band, sizeof(float) * PART_LEN2);
1300 Fft(fft, df); 1344 Fft(fft, nearend_fft);
1301 1345
1302 // Power smoothing. 1346 // Power smoothing.
1303 if (aec->refined_adaptive_filter_enabled) { 1347 if (aec->refined_adaptive_filter_enabled) {
1304 for (i = 0; i < PART_LEN1; ++i) { 1348 for (i = 0; i < PART_LEN1; ++i) {
1305 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + 1349 far_spectrum = farend_fft[0][i] * farend_fft[0][i] +
1306 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); 1350 farend_fft[1][i] * farend_fft[1][i];
1307 // Calculate the magnitude spectrum. 1351 // Calculate the magnitude spectrum.
1308 abs_far_spectrum[i] = sqrtf(far_spectrum); 1352 abs_far_spectrum[i] = sqrtf(far_spectrum);
1309 } 1353 }
1310 RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf, 1354 RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf,
1311 aec->xPow); 1355 aec->xPow);
1312 } else { 1356 } else {
1313 for (i = 0; i < PART_LEN1; ++i) { 1357 for (i = 0; i < PART_LEN1; ++i) {
1314 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + 1358 far_spectrum = farend_fft[0][i] * farend_fft[0][i] +
1315 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); 1359 farend_fft[1][i] * farend_fft[1][i];
1316 aec->xPow[i] = 1360 aec->xPow[i] =
1317 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; 1361 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
1318 // Calculate the magnitude spectrum. 1362 // Calculate the magnitude spectrum.
1319 abs_far_spectrum[i] = sqrtf(far_spectrum); 1363 abs_far_spectrum[i] = sqrtf(far_spectrum);
1320 } 1364 }
1321 } 1365 }
1322 1366
1323 for (i = 0; i < PART_LEN1; ++i) { 1367 for (i = 0; i < PART_LEN1; ++i) {
1324 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; 1368 near_spectrum = nearend_fft[0][i] * nearend_fft[0][i] +
1369 nearend_fft[1][i] * nearend_fft[1][i];
1325 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; 1370 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum;
1326 // Calculate the magnitude spectrum. 1371 // Calculate the magnitude spectrum.
1327 abs_near_spectrum[i] = sqrtf(near_spectrum); 1372 abs_near_spectrum[i] = sqrtf(near_spectrum);
1328 } 1373 }
1329 1374
1330 // Estimate noise power. Wait until dPow is more stable. 1375 // Estimate noise power. Wait until dPow is more stable.
1331 if (aec->noiseEstCtr > 50) { 1376 if (aec->noiseEstCtr > 50) {
1332 for (i = 0; i < PART_LEN1; i++) { 1377 for (i = 0; i < PART_LEN1; i++) {
1333 if (aec->dPow[i] < aec->dMinPow[i]) { 1378 if (aec->dPow[i] < aec->dMinPow[i]) {
1334 aec->dMinPow[i] = 1379 aec->dMinPow[i] =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 if (aec->delay_metrics_delivered == 1 && 1415 if (aec->delay_metrics_delivered == 1 &&
1371 aec->num_delay_values >= kDelayMetricsAggregationWindow) { 1416 aec->num_delay_values >= kDelayMetricsAggregationWindow) {
1372 UpdateDelayMetrics(aec); 1417 UpdateDelayMetrics(aec);
1373 } 1418 }
1374 } 1419 }
1375 } 1420 }
1376 1421
1377 // Perform echo subtraction. 1422 // Perform echo subtraction.
1378 EchoSubtraction(aec->num_partitions, aec->extended_filter_enabled, 1423 EchoSubtraction(aec->num_partitions, aec->extended_filter_enabled,
1379 &aec->extreme_filter_divergence, aec->filter_step_size, 1424 &aec->extreme_filter_divergence, aec->filter_step_size,
1380 aec->error_threshold, &x_fft[0][0], &aec->xfBufBlockPos, 1425 aec->error_threshold, &farend_fft[0][0], &aec->xfBufBlockPos,
1381 aec->xfBuf, &nearend_block[0][0], aec->xPow, aec->wfBuf, 1426 aec->xfBuf, &nearend_block[0][0], aec->xPow, aec->wfBuf,
1382 echo_subtractor_output); 1427 echo_subtractor_output);
1383 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, 1428 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
1384 &aec->wfBuf[0][0]); 1429 &aec->wfBuf[0][0]);
1385 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, 1430 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
1386 &aec->wfBuf[1][0]); 1431 &aec->wfBuf[1][0]);
1387 1432
1388 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output, 1433 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output,
1389 std::min(aec->sampFreq, 16000), 1); 1434 std::min(aec->sampFreq, 16000), 1);
1390 1435
1391 if (aec->metricsMode == 1) { 1436 if (aec->metricsMode == 1) {
1392 UpdateLevel(&aec->linoutlevel, 1437 UpdateLevel(&aec->linoutlevel,
1393 CalculatePower(echo_subtractor_output, PART_LEN)); 1438 CalculatePower(echo_subtractor_output, PART_LEN));
1394 } 1439 }
1395 1440
1396 // Perform echo suppression. 1441 // Perform echo suppression.
1397 EchoSuppression(aec, nearend_extended_block_lowest_band, farend_ptr, 1442 EchoSuppression(aec, nearend_extended_block_lowest_band,
1398 echo_subtractor_output, output_block); 1443 farend_extended_block_lowest_band, echo_subtractor_output,
1444 output_block);
1399 1445
1400 if (aec->metricsMode == 1) { 1446 if (aec->metricsMode == 1) {
1401 UpdateLevel(&aec->nlpoutlevel, 1447 UpdateLevel(&aec->nlpoutlevel,
1402 CalculatePower(&output_block[0][0], PART_LEN)); 1448 CalculatePower(&output_block[0][0], PART_LEN));
1403 UpdateMetrics(aec); 1449 UpdateMetrics(aec);
1404 } 1450 }
1405 1451
1406 // Store the nearend signal until the next frame. 1452 // Store the nearend signal until the next frame.
1407 for (i = 0; i < aec->num_bands; ++i) { 1453 for (i = 0; i < aec->num_bands; ++i) {
1408 memcpy(&aec->previous_nearend_block[i][0], &nearend_block[i][0], 1454 memcpy(&aec->previous_nearend_block[i][0], &nearend_block[i][0],
(...skipping 10 matching lines...) Expand all
1419 if (!aec) { 1465 if (!aec) {
1420 return NULL; 1466 return NULL;
1421 } 1467 }
1422 aec->nearend_buffer_size = 0; 1468 aec->nearend_buffer_size = 0;
1423 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer)); 1469 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
1424 // Start the output buffer with zeros to be able to produce 1470 // Start the output buffer with zeros to be able to produce
1425 // a full output frame in the first frame. 1471 // a full output frame in the first frame.
1426 aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN); 1472 aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN);
1427 memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer)); 1473 memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer));
1428 1474
1429 // Create far-end buffers.
1430 // For bit exactness with legacy code, each element in |far_time_buf| is
1431 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN|
1432 // samples from the last frame.
1433 // TODO(minyue): reduce |far_time_buf| to non-overlapped |PART_LEN| samples.
1434 aec->far_time_buf =
1435 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * PART_LEN2);
1436 if (!aec->far_time_buf) {
1437 WebRtcAec_FreeAec(aec);
1438 return NULL;
1439 }
1440
1441 aec->delay_estimator_farend = 1475 aec->delay_estimator_farend =
1442 WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks); 1476 WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks);
1443 if (aec->delay_estimator_farend == NULL) { 1477 if (aec->delay_estimator_farend == NULL) {
1444 WebRtcAec_FreeAec(aec); 1478 WebRtcAec_FreeAec(aec);
1445 return NULL; 1479 return NULL;
1446 } 1480 }
1447 // We create the delay_estimator with the same amount of maximum lookahead as 1481 // We create the delay_estimator with the same amount of maximum lookahead as
1448 // the delay history size (kHistorySizeBlocks) for symmetry reasons. 1482 // the delay history size (kHistorySizeBlocks) for symmetry reasons.
1449 aec->delay_estimator = WebRtc_CreateDelayEstimator( 1483 aec->delay_estimator = WebRtc_CreateDelayEstimator(
1450 aec->delay_estimator_farend, kHistorySizeBlocks); 1484 aec->delay_estimator_farend, kHistorySizeBlocks);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 aec_rdft_init(); 1528 aec_rdft_init();
1495 1529
1496 return aec; 1530 return aec;
1497 } 1531 }
1498 1532
1499 void WebRtcAec_FreeAec(AecCore* aec) { 1533 void WebRtcAec_FreeAec(AecCore* aec) {
1500 if (aec == NULL) { 1534 if (aec == NULL) {
1501 return; 1535 return;
1502 } 1536 }
1503 1537
1504 WebRtc_FreeBuffer(aec->far_time_buf);
1505
1506 WebRtc_FreeDelayEstimator(aec->delay_estimator); 1538 WebRtc_FreeDelayEstimator(aec->delay_estimator);
1507 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); 1539 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend);
1508 1540
1509 delete aec; 1541 delete aec;
1510 } 1542 }
1511 1543
1512 static void SetAdaptiveFilterStepSize(AecCore* aec) { 1544 static void SetAdaptiveFilterStepSize(AecCore* aec) {
1513 // Extended filter adaptation parameter. 1545 // Extended filter adaptation parameter.
1514 // TODO(ajm): No narrowband tuning yet. 1546 // TODO(ajm): No narrowband tuning yet.
1515 const float kExtendedMu = 0.4f; 1547 const float kExtendedMu = 0.4f;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 aec->num_bands = (size_t)(sampFreq / 16000); 1592 aec->num_bands = (size_t)(sampFreq / 16000);
1561 } 1593 }
1562 1594
1563 // Start the output buffer with zeros to be able to produce 1595 // Start the output buffer with zeros to be able to produce
1564 // a full output frame in the first frame. 1596 // a full output frame in the first frame.
1565 aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN); 1597 aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN);
1566 memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer)); 1598 memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer));
1567 aec->nearend_buffer_size = 0; 1599 aec->nearend_buffer_size = 0;
1568 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer)); 1600 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
1569 1601
1570 // Initialize far-end buffers. 1602 // Initialize far-end buffer.
1571 WebRtc_InitBuffer(aec->far_time_buf); 1603 aec->farend_block_buffer_.ReInit();
1572 1604
1573 aec->system_delay = 0; 1605 aec->system_delay = 0;
1574 1606
1575 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { 1607 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) {
1576 return -1; 1608 return -1;
1577 } 1609 }
1578 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { 1610 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) {
1579 return -1; 1611 return -1;
1580 } 1612 }
1581 aec->delay_logging_enabled = 0; 1613 aec->delay_logging_enabled = 0;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 1712
1681 aec->extreme_filter_divergence = 0; 1713 aec->extreme_filter_divergence = 0;
1682 1714
1683 // Metrics disabled by default 1715 // Metrics disabled by default
1684 aec->metricsMode = 0; 1716 aec->metricsMode = 0;
1685 InitMetrics(aec); 1717 InitMetrics(aec);
1686 1718
1687 return 0; 1719 return 0;
1688 } 1720 }
1689 1721
1690 // For bit exactness with a legacy code, |farend| is supposed to contain 1722 void WebRtcAec_BufferFarendBlock(AecCore* aec, const float* farend) {
1691 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last
1692 // frame.
1693 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples.
1694 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) {
1695 // Check if the buffer is full, and in that case flush the oldest data. 1723 // Check if the buffer is full, and in that case flush the oldest data.
1696 if (WebRtc_available_write(aec->far_time_buf) < 1) { 1724 if (aec->farend_block_buffer_.AvaliableSpace() < 1) {
1697 WebRtcAec_MoveFarReadPtr(aec, 1); 1725 aec->farend_block_buffer_.AdjustSize(1);
1698 } 1726 }
1699 1727 aec->farend_block_buffer_.Insert(farend);
1700 WebRtc_WriteBuffer(aec->far_time_buf, farend, 1);
1701 } 1728 }
1702 1729
1703 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { 1730 int WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(AecCore* aec,
1704 int elements_moved = WebRtc_MoveReadPtr(aec->far_time_buf, elements); 1731 int buffer_size_decrease) {
1705 aec->system_delay -= elements_moved * PART_LEN; 1732 int achieved_buffer_size_decrease =
1706 return elements_moved; 1733 aec->farend_block_buffer_.AdjustSize(buffer_size_decrease);
1734 aec->system_delay -= achieved_buffer_size_decrease * PART_LEN;
1735 return achieved_buffer_size_decrease;
1707 } 1736 }
1708 1737
1709 void FormNearendBlock( 1738 void FormNearendBlock(
1710 size_t nearend_start_index, 1739 size_t nearend_start_index,
1711 size_t num_bands, 1740 size_t num_bands,
1712 const float* const* nearend_frame, 1741 const float* const* nearend_frame,
1713 size_t num_samples_from_nearend_frame, 1742 size_t num_samples_from_nearend_frame,
1714 const float nearend_buffer[NUM_HIGH_BANDS_MAX + 1] 1743 const float nearend_buffer[NUM_HIGH_BANDS_MAX + 1]
1715 [PART_LEN - (FRAME_LEN - PART_LEN)], 1744 [PART_LEN - (FRAME_LEN - PART_LEN)],
1716 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) { 1745 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 // allow one algorithm to be turned on. 1847 // allow one algorithm to be turned on.
1819 1848
1820 assert(aec->num_bands == num_bands); 1849 assert(aec->num_bands == num_bands);
1821 1850
1822 for (size_t j = 0; j < num_samples; j += FRAME_LEN) { 1851 for (size_t j = 0; j < num_samples; j += FRAME_LEN) {
1823 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we 1852 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we
1824 // have enough far-end data for that by stuffing the buffer if the 1853 // have enough far-end data for that by stuffing the buffer if the
1825 // |system_delay| indicates others. 1854 // |system_delay| indicates others.
1826 if (aec->system_delay < FRAME_LEN) { 1855 if (aec->system_delay < FRAME_LEN) {
1827 // We don't have enough data so we rewind 10 ms. 1856 // We don't have enough data so we rewind 10 ms.
1828 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); 1857 WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aec, -(aec->mult + 1));
1829 } 1858 }
1830 1859
1831 if (!aec->delay_agnostic_enabled) { 1860 if (!aec->delay_agnostic_enabled) {
1832 // 2 a) Compensate for a possible change in the system delay. 1861 // 2 a) Compensate for a possible change in the system delay.
1833 1862
1834 // TODO(bjornv): Investigate how we should round the delay difference; 1863 // TODO(bjornv): Investigate how we should round the delay difference;
1835 // right now we know that incoming |knownDelay| is underestimated when 1864 // right now we know that incoming |knownDelay| is underestimated when
1836 // it's less than |aec->knownDelay|. We therefore, round (-32) in that 1865 // it's less than |aec->knownDelay|. We therefore, round (-32) in that
1837 // direction. In the other direction, we don't have this situation, but 1866 // direction. In the other direction, we don't have this situation, but
1838 // might flush one partition too little. This can cause non-causality, 1867 // might flush one partition too little. This can cause non-causality,
1839 // which should be investigated. Maybe, allow for a non-symmetric 1868 // which should be investigated. Maybe, allow for a non-symmetric
1840 // rounding, like -16. 1869 // rounding, like -16.
1841 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; 1870 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN;
1842 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); 1871 int moved_elements = aec->farend_block_buffer_.AdjustSize(move_elements);
1843 MaybeLogDelayAdjustment(moved_elements * (aec->sampFreq == 8000 ? 8 : 4), 1872 MaybeLogDelayAdjustment(moved_elements * (aec->sampFreq == 8000 ? 8 : 4),
1844 DelaySource::kSystemDelay); 1873 DelaySource::kSystemDelay);
1845 aec->knownDelay -= moved_elements * PART_LEN; 1874 aec->knownDelay -= moved_elements * PART_LEN;
1846 } else { 1875 } else {
1847 // 2 b) Apply signal based delay correction. 1876 // 2 b) Apply signal based delay correction.
1848 int move_elements = SignalBasedDelayCorrection(aec); 1877 int move_elements = SignalBasedDelayCorrection(aec);
1849 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); 1878 int moved_elements = aec->farend_block_buffer_.AdjustSize(move_elements);
1850 MaybeLogDelayAdjustment(moved_elements * (aec->sampFreq == 8000 ? 8 : 4), 1879 MaybeLogDelayAdjustment(moved_elements * (aec->sampFreq == 8000 ? 8 : 4),
1851 DelaySource::kDelayAgnostic); 1880 DelaySource::kDelayAgnostic);
1852 int far_near_buffer_diff = 1881 int far_near_buffer_diff =
1853 WebRtc_available_read(aec->far_time_buf) - 1882 aec->farend_block_buffer_.Size() -
1854 (aec->nearend_buffer_size + FRAME_LEN) / PART_LEN; 1883 (aec->nearend_buffer_size + FRAME_LEN) / PART_LEN;
1855 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); 1884 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements);
1856 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, 1885 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend,
1857 moved_elements); 1886 moved_elements);
1858 aec->signal_delay_correction += moved_elements; 1887 aec->signal_delay_correction += moved_elements;
1859 // If we rely on reported system delay values only, a buffer underrun here 1888 // If we rely on reported system delay values only, a buffer underrun here
1860 // can never occur since we've taken care of that in 1) above. Here, we 1889 // can never occur since we've taken care of that in 1) above. Here, we
1861 // apply signal based delay correction and can therefore end up with 1890 // apply signal based delay correction and can therefore end up with
1862 // buffer underruns since the delay estimation can be wrong. We therefore 1891 // buffer underruns since the delay estimation can be wrong. We therefore
1863 // stuff the buffer with enough elements if needed. 1892 // stuff the buffer with enough elements if needed.
1864 if (far_near_buffer_diff < 0) { 1893 if (far_near_buffer_diff < 0) {
1865 WebRtcAec_MoveFarReadPtr(aec, far_near_buffer_diff); 1894 WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aec,
1895 far_near_buffer_diff);
1866 } 1896 }
1867 } 1897 }
1868 1898
1869 static_assert( 1899 static_assert(
1870 16 == (FRAME_LEN - PART_LEN), 1900 16 == (FRAME_LEN - PART_LEN),
1871 "These constants need to be properly related for this code to work"); 1901 "These constants need to be properly related for this code to work");
1872 float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]; 1902 float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN];
1873 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]; 1903 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN];
1904 float farend_extended_block_lowest_band[PART_LEN2];
1874 1905
1875 // Form and process a block of nearend samples, buffer the output block of 1906 // Form and process a block of nearend samples, buffer the output block of
1876 // samples. 1907 // samples.
1908 aec->farend_block_buffer_.ExtractExtendedBlock(
1909 farend_extended_block_lowest_band);
1877 FormNearendBlock(j, num_bands, nearend, PART_LEN - aec->nearend_buffer_size, 1910 FormNearendBlock(j, num_bands, nearend, PART_LEN - aec->nearend_buffer_size,
1878 aec->nearend_buffer, nearend_block); 1911 aec->nearend_buffer, nearend_block);
1879 ProcessBlock(aec, nearend_block, output_block); 1912 ProcessNearendBlock(aec, farend_extended_block_lowest_band, nearend_block,
1913 output_block);
1880 BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size, 1914 BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size,
1881 aec->output_buffer); 1915 aec->output_buffer);
1882 1916
1883 if ((FRAME_LEN - PART_LEN + aec->nearend_buffer_size) == PART_LEN) { 1917 if ((FRAME_LEN - PART_LEN + aec->nearend_buffer_size) == PART_LEN) {
1884 // When possible (every fourth frame) form and process a second block of 1918 // When possible (every fourth frame) form and process a second block of
1885 // nearend samples, buffer the output block of samples. 1919 // nearend samples, buffer the output block of samples.
1920 aec->farend_block_buffer_.ExtractExtendedBlock(
1921 farend_extended_block_lowest_band);
1886 FormNearendBlock(j + FRAME_LEN - PART_LEN, num_bands, nearend, PART_LEN, 1922 FormNearendBlock(j + FRAME_LEN - PART_LEN, num_bands, nearend, PART_LEN,
1887 aec->nearend_buffer, nearend_block); 1923 aec->nearend_buffer, nearend_block);
1888 ProcessBlock(aec, nearend_block, output_block); 1924 ProcessNearendBlock(aec, farend_extended_block_lowest_band, nearend_block,
1925 output_block);
1889 BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size, 1926 BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size,
1890 aec->output_buffer); 1927 aec->output_buffer);
1891 1928
1892 // Reset the buffer size as there are no samples left in the nearend input 1929 // Reset the buffer size as there are no samples left in the nearend input
1893 // to buffer. 1930 // to buffer.
1894 aec->nearend_buffer_size = 0; 1931 aec->nearend_buffer_size = 0;
1895 } else { 1932 } else {
1896 // Buffer the remaining samples in the nearend input. 1933 // Buffer the remaining samples in the nearend input.
1897 aec->nearend_buffer_size += FRAME_LEN - PART_LEN; 1934 aec->nearend_buffer_size += FRAME_LEN - PART_LEN;
1898 BufferNearendFrame(j, num_bands, nearend, aec->nearend_buffer_size, 1935 BufferNearendFrame(j, num_bands, nearend, aec->nearend_buffer_size,
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 2048
2012 int WebRtcAec_system_delay(AecCore* self) { 2049 int WebRtcAec_system_delay(AecCore* self) {
2013 return self->system_delay; 2050 return self->system_delay;
2014 } 2051 }
2015 2052
2016 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 2053 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
2017 assert(delay >= 0); 2054 assert(delay >= 0);
2018 self->system_delay = delay; 2055 self->system_delay = delay;
2019 } 2056 }
2020 } // namespace webrtc 2057 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/aec/aec_core.h ('k') | webrtc/modules/audio_processing/aec/echo_cancellation.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698