| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |