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 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 static int SignalBasedDelayCorrection(AecCore* self) { | 820 static int SignalBasedDelayCorrection(AecCore* self) { |
821 int delay_correction = 0; | 821 int delay_correction = 0; |
822 int last_delay = -2; | 822 int last_delay = -2; |
823 assert(self != NULL); | 823 assert(self != NULL); |
824 #if !defined(WEBRTC_ANDROID) | 824 #if !defined(WEBRTC_ANDROID) |
825 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This | 825 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This |
826 // is to let the delay estimation get a chance to converge. Also, if the | 826 // is to let the delay estimation get a chance to converge. Also, if the |
827 // playout audio volume is low (or even muted) the delay estimation can return | 827 // playout audio volume is low (or even muted) the delay estimation can return |
828 // a very large delay, which will break the AEC if it is applied. | 828 // a very large delay, which will break the AEC if it is applied. |
829 if (self->frame_count < kDelayCorrectionStart) { | 829 if (self->frame_count < kDelayCorrectionStart) { |
| 830 self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay); |
830 return 0; | 831 return 0; |
831 } | 832 } |
832 #endif | 833 #endif |
833 | 834 |
834 // 1. Check for non-negative delay estimate. Note that the estimates we get | 835 // 1. Check for non-negative delay estimate. Note that the estimates we get |
835 // from the delay estimation are not compensated for lookahead. Hence, a | 836 // from the delay estimation are not compensated for lookahead. Hence, a |
836 // negative |last_delay| is an invalid one. | 837 // negative |last_delay| is an invalid one. |
837 // 2. Verify that there is a delay change. In addition, only allow a change | 838 // 2. Verify that there is a delay change. In addition, only allow a change |
838 // if the delay is outside a certain region taking the AEC filter length | 839 // if the delay is outside a certain region taking the AEC filter length |
839 // into account. | 840 // into account. |
840 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. | 841 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. |
841 // 3. Only allow delay correction if the delay estimation quality exceeds | 842 // 3. Only allow delay correction if the delay estimation quality exceeds |
842 // |delay_quality_threshold|. | 843 // |delay_quality_threshold|. |
843 // 4. Finally, verify that the proposed |delay_correction| is feasible by | 844 // 4. Finally, verify that the proposed |delay_correction| is feasible by |
844 // comparing with the size of the far-end buffer. | 845 // comparing with the size of the far-end buffer. |
845 last_delay = WebRtc_last_delay(self->delay_estimator); | 846 last_delay = WebRtc_last_delay(self->delay_estimator); |
| 847 self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay); |
846 if ((last_delay >= 0) && (last_delay != self->previous_delay) && | 848 if ((last_delay >= 0) && (last_delay != self->previous_delay) && |
847 (WebRtc_last_delay_quality(self->delay_estimator) > | 849 (WebRtc_last_delay_quality(self->delay_estimator) > |
848 self->delay_quality_threshold)) { | 850 self->delay_quality_threshold)) { |
849 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); | 851 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); |
850 // Allow for a slack in the actual delay, defined by a |lower_bound| and an | 852 // Allow for a slack in the actual delay, defined by a |lower_bound| and an |
851 // |upper_bound|. The adaptive echo cancellation filter is currently | 853 // |upper_bound|. The adaptive echo cancellation filter is currently |
852 // |num_partitions| (of 64 samples) long. If the delay estimate is negative | 854 // |num_partitions| (of 64 samples) long. If the delay estimate is negative |
853 // or at least 3/4 of the filter length we open up for correction. | 855 // or at least 3/4 of the filter length we open up for correction. |
854 const int lower_bound = 0; | 856 const int lower_bound = 0; |
855 const int upper_bound = self->num_partitions * 3 / 4; | 857 const int upper_bound = self->num_partitions * 3 / 4; |
(...skipping 25 matching lines...) Expand all Loading... |
881 if (self->delay_correction_count > 0) { | 883 if (self->delay_correction_count > 0) { |
882 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); | 884 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); |
883 delay_quality = | 885 delay_quality = |
884 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax | 886 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax |
885 : delay_quality); | 887 : delay_quality); |
886 self->delay_quality_threshold = | 888 self->delay_quality_threshold = |
887 (delay_quality > self->delay_quality_threshold | 889 (delay_quality > self->delay_quality_threshold |
888 ? delay_quality | 890 ? delay_quality |
889 : self->delay_quality_threshold); | 891 : self->delay_quality_threshold); |
890 } | 892 } |
| 893 self->data_dumper->DumpRaw("aec_da_delay_correction", 1, &delay_correction); |
| 894 |
891 return delay_correction; | 895 return delay_correction; |
892 } | 896 } |
893 | 897 |
894 static void RegressorPower(int num_partitions, | 898 static void RegressorPower(int num_partitions, |
895 int latest_added_partition, | 899 int latest_added_partition, |
896 float x_fft_buf[2] | 900 float x_fft_buf[2] |
897 [kExtendedNumPartitions * PART_LEN1], | 901 [kExtendedNumPartitions * PART_LEN1], |
898 float x_pow[PART_LEN1]) { | 902 float x_pow[PART_LEN1]) { |
899 RTC_DCHECK_LT(latest_added_partition, num_partitions); | 903 RTC_DCHECK_LT(latest_added_partition, num_partitions); |
900 memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0])); | 904 memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0])); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 | 1151 |
1148 // Buffer far. | 1152 // Buffer far. |
1149 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); | 1153 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); |
1150 | 1154 |
1151 aec->delayEstCtr++; | 1155 aec->delayEstCtr++; |
1152 if (aec->delayEstCtr == delayEstInterval) { | 1156 if (aec->delayEstCtr == delayEstInterval) { |
1153 aec->delayEstCtr = 0; | 1157 aec->delayEstCtr = 0; |
1154 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); | 1158 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); |
1155 } | 1159 } |
1156 | 1160 |
| 1161 aec->data_dumper->DumpRaw("aec_nlp_delay", 1, &aec->delayIdx); |
| 1162 |
1157 // Use delayed far. | 1163 // Use delayed far. |
1158 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, | 1164 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, |
1159 sizeof(xfw[0][0]) * 2 * PART_LEN1); | 1165 sizeof(xfw[0][0]) * 2 * PART_LEN1); |
1160 | 1166 |
1161 WebRtcAec_UpdateCoherenceSpectra(aec->mult, aec->extended_filter_enabled == 1, | 1167 WebRtcAec_UpdateCoherenceSpectra(aec->mult, aec->extended_filter_enabled == 1, |
1162 efw, dfw, xfw, &aec->coherence_state, | 1168 efw, dfw, xfw, &aec->coherence_state, |
1163 &aec->divergeState, | 1169 &aec->divergeState, |
1164 &aec->extreme_filter_divergence); | 1170 &aec->extreme_filter_divergence); |
1165 | 1171 |
1166 WebRtcAec_ComputeCoherence(&aec->coherence_state, cohde, cohxd); | 1172 WebRtcAec_ComputeCoherence(&aec->coherence_state, cohde, cohxd); |
1167 | 1173 |
1168 // Select the microphone signal as output if the filter is deemed to have | 1174 // Select the microphone signal as output if the filter is deemed to have |
1169 // diverged. | 1175 // diverged. |
1170 if (aec->divergeState) { | 1176 if (aec->divergeState) { |
1171 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); | 1177 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); |
1172 } | 1178 } |
1173 | 1179 |
1174 FormSuppressionGain(aec, cohde, cohxd, hNl); | 1180 FormSuppressionGain(aec, cohde, cohxd, hNl); |
1175 | 1181 |
| 1182 aec->data_dumper->DumpRaw("aec_nlp_gain", PART_LEN1, hNl); |
| 1183 |
1176 WebRtcAec_Suppress(hNl, efw); | 1184 WebRtcAec_Suppress(hNl, efw); |
1177 | 1185 |
1178 // Add comfort noise. | 1186 // Add comfort noise. |
1179 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband, | 1187 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband, |
1180 aec->noisePow, hNl); | 1188 aec->noisePow, hNl); |
1181 | 1189 |
1182 // Inverse error fft. | 1190 // Inverse error fft. |
1183 ScaledInverseFft(efw, fft, 2.0f, 1); | 1191 ScaledInverseFft(efw, fft, 2.0f, 1); |
1184 | 1192 |
1185 // Overlap and add to obtain output. | 1193 // Overlap and add to obtain output. |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 } | 1389 } |
1382 } | 1390 } |
1383 } | 1391 } |
1384 | 1392 |
1385 // Perform echo subtraction. | 1393 // Perform echo subtraction. |
1386 EchoSubtraction(aec->num_partitions, aec->extended_filter_enabled, | 1394 EchoSubtraction(aec->num_partitions, aec->extended_filter_enabled, |
1387 &aec->extreme_filter_divergence, aec->filter_step_size, | 1395 &aec->extreme_filter_divergence, aec->filter_step_size, |
1388 aec->error_threshold, &x_fft[0][0], &aec->xfBufBlockPos, | 1396 aec->error_threshold, &x_fft[0][0], &aec->xfBufBlockPos, |
1389 aec->xfBuf, nearend_ptr, aec->xPow, aec->wfBuf, | 1397 aec->xfBuf, nearend_ptr, aec->xPow, aec->wfBuf, |
1390 echo_subtractor_output); | 1398 echo_subtractor_output); |
| 1399 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, |
| 1400 &aec->wfBuf[0][0]); |
| 1401 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, |
| 1402 &aec->wfBuf[1][0]); |
1391 | 1403 |
1392 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output, | 1404 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output, |
1393 std::min(aec->sampFreq, 16000), 1); | 1405 std::min(aec->sampFreq, 16000), 1); |
1394 | 1406 |
1395 if (aec->metricsMode == 1) { | 1407 if (aec->metricsMode == 1) { |
1396 UpdateLevel(&aec->linoutlevel, | 1408 UpdateLevel(&aec->linoutlevel, |
1397 CalculatePower(echo_subtractor_output, PART_LEN)); | 1409 CalculatePower(echo_subtractor_output, PART_LEN)); |
1398 } | 1410 } |
1399 | 1411 |
1400 // Perform echo suppression. | 1412 // Perform echo suppression. |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1969 | 1981 |
1970 int WebRtcAec_system_delay(AecCore* self) { | 1982 int WebRtcAec_system_delay(AecCore* self) { |
1971 return self->system_delay; | 1983 return self->system_delay; |
1972 } | 1984 } |
1973 | 1985 |
1974 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1986 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1975 assert(delay >= 0); | 1987 assert(delay >= 0); |
1976 self->system_delay = delay; | 1988 self->system_delay = delay; |
1977 } | 1989 } |
1978 } // namespace webrtc | 1990 } // namespace webrtc |
OLD | NEW |