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

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

Issue 1187943005: Reland "Revert "audio_processing/aec: make delay estimator aware of starving farend buffer"" (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Adjusted device buffer mapping w.r.t. extended_filter Created 5 years, 6 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
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/echo_cancellation.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 freq_data[1][0] = 0; 850 freq_data[1][0] = 0;
851 freq_data[1][PART_LEN] = 0; 851 freq_data[1][PART_LEN] = 0;
852 freq_data[0][0] = time_data[0]; 852 freq_data[0][0] = time_data[0];
853 freq_data[0][PART_LEN] = time_data[1]; 853 freq_data[0][PART_LEN] = time_data[1];
854 for (i = 1; i < PART_LEN; i++) { 854 for (i = 1; i < PART_LEN; i++) {
855 freq_data[0][i] = time_data[2 * i]; 855 freq_data[0][i] = time_data[2 * i];
856 freq_data[1][i] = time_data[2 * i + 1]; 856 freq_data[1][i] = time_data[2 * i + 1];
857 } 857 }
858 } 858 }
859 859
860 static int MoveFarReadPtrWithoutSystemDelayUpdate(AecCore* self, int elements) {
861 WebRtc_MoveReadPtr(self->far_buf_windowed, elements);
862 #ifdef WEBRTC_AEC_DEBUG_DUMP
863 WebRtc_MoveReadPtr(self->far_time_buf, elements);
864 #endif
865 return WebRtc_MoveReadPtr(self->far_buf, elements);
866 }
867
860 static int SignalBasedDelayCorrection(AecCore* self) { 868 static int SignalBasedDelayCorrection(AecCore* self) {
861 int delay_correction = 0; 869 int delay_correction = 0;
862 int last_delay = -2; 870 int last_delay = -2;
863 assert(self != NULL); 871 assert(self != NULL);
864 #if !defined(WEBRTC_ANDROID) 872 #if !defined(WEBRTC_ANDROID)
865 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This 873 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This
866 // is to let the delay estimation get a chance to converge. Also, if the 874 // is to let the delay estimation get a chance to converge. Also, if the
867 // playout audio volume is low (or even muted) the delay estimation can return 875 // playout audio volume is low (or even muted) the delay estimation can return
868 // a very large delay, which will break the AEC if it is applied. 876 // a very large delay, which will break the AEC if it is applied.
869 if (self->frame_count < kDelayCorrectionStart) { 877 if (self->frame_count < kDelayCorrectionStart) {
(...skipping 20 matching lines...) Expand all
890 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); 898 int delay = last_delay - WebRtc_lookahead(self->delay_estimator);
891 // Allow for a slack in the actual delay, defined by a |lower_bound| and an 899 // Allow for a slack in the actual delay, defined by a |lower_bound| and an
892 // |upper_bound|. The adaptive echo cancellation filter is currently 900 // |upper_bound|. The adaptive echo cancellation filter is currently
893 // |num_partitions| (of 64 samples) long. If the delay estimate is negative 901 // |num_partitions| (of 64 samples) long. If the delay estimate is negative
894 // or at least 3/4 of the filter length we open up for correction. 902 // or at least 3/4 of the filter length we open up for correction.
895 const int lower_bound = 0; 903 const int lower_bound = 0;
896 const int upper_bound = self->num_partitions * 3 / 4; 904 const int upper_bound = self->num_partitions * 3 / 4;
897 const int do_correction = delay <= lower_bound || delay > upper_bound; 905 const int do_correction = delay <= lower_bound || delay > upper_bound;
898 if (do_correction == 1) { 906 if (do_correction == 1) {
899 int available_read = (int)WebRtc_available_read(self->far_buf); 907 int available_read = (int)WebRtc_available_read(self->far_buf);
900 // Adjust w.r.t. a |shift_offset| to account for not as reliable estimates 908 // With |shift_offset| we gradually rely on the delay estimates. For
901 // in the beginning, hence we are more conservative. 909 // positive delays we reduce the correction by |shift_offset| to lower the
902 delay_correction = -(delay - self->shift_offset); 910 // risk of pushing the AEC into a non causal state. For negative delays
911 // we rely on the values up to a rounding error, hence compensate by 1
912 // element to make sure to push the delay into the causal region.
913 delay_correction = -delay;
914 delay_correction += delay > self->shift_offset ? self->shift_offset : 1;
903 self->shift_offset--; 915 self->shift_offset--;
904 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); 916 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset);
905 if (delay_correction > available_read - self->mult - 1) { 917 if (delay_correction > available_read - self->mult - 1) {
906 // There is not enough data in the buffer to perform this shift. Hence, 918 // There is not enough data in the buffer to perform this shift. Hence,
907 // we do not rely on the delay estimate and do nothing. 919 // we do not rely on the delay estimate and do nothing.
908 delay_correction = 0; 920 delay_correction = 0;
909 } else { 921 } else {
910 self->previous_delay = last_delay; 922 self->previous_delay = last_delay;
911 ++self->delay_correction_count; 923 ++self->delay_correction_count;
912 } 924 }
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 } 1445 }
1434 // We create the delay_estimator with the same amount of maximum lookahead as 1446 // We create the delay_estimator with the same amount of maximum lookahead as
1435 // the delay history size (kHistorySizeBlocks) for symmetry reasons. 1447 // the delay history size (kHistorySizeBlocks) for symmetry reasons.
1436 aec->delay_estimator = WebRtc_CreateDelayEstimator( 1448 aec->delay_estimator = WebRtc_CreateDelayEstimator(
1437 aec->delay_estimator_farend, kHistorySizeBlocks); 1449 aec->delay_estimator_farend, kHistorySizeBlocks);
1438 if (aec->delay_estimator == NULL) { 1450 if (aec->delay_estimator == NULL) {
1439 WebRtcAec_FreeAec(aec); 1451 WebRtcAec_FreeAec(aec);
1440 return NULL; 1452 return NULL;
1441 } 1453 }
1442 #ifdef WEBRTC_ANDROID 1454 #ifdef WEBRTC_ANDROID
1455 aec->reported_delay_enabled = 0; // DA-AEC enabled by default.
1443 // DA-AEC assumes the system is causal from the beginning and will self adjust 1456 // DA-AEC assumes the system is causal from the beginning and will self adjust
1444 // the lookahead when shifting is required. 1457 // the lookahead when shifting is required.
1445 WebRtc_set_lookahead(aec->delay_estimator, 0); 1458 WebRtc_set_lookahead(aec->delay_estimator, 0);
1446 #else 1459 #else
1460 aec->reported_delay_enabled = 1;
1447 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); 1461 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks);
1448 #endif 1462 #endif
1463 aec->extended_filter_enabled = 0;
1449 1464
1450 // Assembly optimization 1465 // Assembly optimization
1451 WebRtcAec_FilterFar = FilterFar; 1466 WebRtcAec_FilterFar = FilterFar;
1452 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; 1467 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal;
1453 WebRtcAec_FilterAdaptation = FilterAdaptation; 1468 WebRtcAec_FilterAdaptation = FilterAdaptation;
1454 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; 1469 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress;
1455 WebRtcAec_ComfortNoise = ComfortNoise; 1470 WebRtcAec_ComfortNoise = ComfortNoise;
1456 WebRtcAec_SubbandCoherence = SubbandCoherence; 1471 WebRtcAec_SubbandCoherence = SubbandCoherence;
1457 1472
1458 #if defined(WEBRTC_ARCH_X86_FAMILY) 1473 #if defined(WEBRTC_ARCH_X86_FAMILY)
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 aec->delay_median = -1; 1600 aec->delay_median = -1;
1586 aec->delay_std = -1; 1601 aec->delay_std = -1;
1587 aec->fraction_poor_delays = -1.0f; 1602 aec->fraction_poor_delays = -1.0f;
1588 1603
1589 aec->signal_delay_correction = 0; 1604 aec->signal_delay_correction = 0;
1590 aec->previous_delay = -2; // (-2): Uninitialized. 1605 aec->previous_delay = -2; // (-2): Uninitialized.
1591 aec->delay_correction_count = 0; 1606 aec->delay_correction_count = 0;
1592 aec->shift_offset = kInitialShiftOffset; 1607 aec->shift_offset = kInitialShiftOffset;
1593 aec->delay_quality_threshold = kDelayQualityThresholdMin; 1608 aec->delay_quality_threshold = kDelayQualityThresholdMin;
1594 1609
1595 #ifdef WEBRTC_ANDROID
1596 aec->reported_delay_enabled = 0; // Disabled by default.
1597 #else
1598 aec->reported_delay_enabled = 1;
1599 #endif
1600 aec->extended_filter_enabled = 0;
1601 aec->num_partitions = kNormalNumPartitions; 1610 aec->num_partitions = kNormalNumPartitions;
1602 1611
1603 // Update the delay estimator with filter length. We use half the 1612 // Update the delay estimator with filter length. We use half the
1604 // |num_partitions| to take the echo path into account. In practice we say 1613 // |num_partitions| to take the echo path into account. In practice we say
1605 // that the echo has a duration of maximum half |num_partitions|, which is not 1614 // that the echo has a duration of maximum half |num_partitions|, which is not
1606 // true, but serves as a crude measure. 1615 // true, but serves as a crude measure.
1607 WebRtc_set_allowed_offset(aec->delay_estimator, aec->num_partitions / 2); 1616 WebRtc_set_allowed_offset(aec->delay_estimator, aec->num_partitions / 2);
1608 // TODO(bjornv): I currently hard coded the enable. Once we've established 1617 // TODO(bjornv): I currently hard coded the enable. Once we've established
1609 // that AECM has no performance regression, robust_validation will be enabled 1618 // that AECM has no performance regression, robust_validation will be enabled
1610 // all the time and the APIs to turn it on/off will be removed. Hence, remove 1619 // all the time and the APIs to turn it on/off will be removed. Hence, remove
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 TimeToFrequency(fft, xf, 0); 1717 TimeToFrequency(fft, xf, 0);
1709 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); 1718 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1);
1710 1719
1711 // Convert far-end partition to the frequency domain with windowing. 1720 // Convert far-end partition to the frequency domain with windowing.
1712 memcpy(fft, farend, sizeof(float) * PART_LEN2); 1721 memcpy(fft, farend, sizeof(float) * PART_LEN2);
1713 TimeToFrequency(fft, xf, 1); 1722 TimeToFrequency(fft, xf, 1);
1714 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); 1723 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1);
1715 } 1724 }
1716 1725
1717 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { 1726 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) {
1718 int elements_moved = WebRtc_MoveReadPtr(aec->far_buf_windowed, elements); 1727 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements);
1719 WebRtc_MoveReadPtr(aec->far_buf, elements);
1720 #ifdef WEBRTC_AEC_DEBUG_DUMP
1721 WebRtc_MoveReadPtr(aec->far_time_buf, elements);
1722 #endif
1723 aec->system_delay -= elements_moved * PART_LEN; 1728 aec->system_delay -= elements_moved * PART_LEN;
1724 return elements_moved; 1729 return elements_moved;
1725 } 1730 }
1726 1731
1727 void WebRtcAec_ProcessFrames(AecCore* aec, 1732 void WebRtcAec_ProcessFrames(AecCore* aec,
1728 const float* const* nearend, 1733 const float* const* nearend,
1729 int num_bands, 1734 int num_bands,
1730 int num_samples, 1735 int num_samples,
1731 int knownDelay, 1736 int knownDelay,
1732 float* const* out) { 1737 float* const* out) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1785 // 2 a) Compensate for a possible change in the system delay. 1790 // 2 a) Compensate for a possible change in the system delay.
1786 1791
1787 // TODO(bjornv): Investigate how we should round the delay difference; 1792 // TODO(bjornv): Investigate how we should round the delay difference;
1788 // right now we know that incoming |knownDelay| is underestimated when 1793 // right now we know that incoming |knownDelay| is underestimated when
1789 // it's less than |aec->knownDelay|. We therefore, round (-32) in that 1794 // it's less than |aec->knownDelay|. We therefore, round (-32) in that
1790 // direction. In the other direction, we don't have this situation, but 1795 // direction. In the other direction, we don't have this situation, but
1791 // might flush one partition too little. This can cause non-causality, 1796 // might flush one partition too little. This can cause non-causality,
1792 // which should be investigated. Maybe, allow for a non-symmetric 1797 // which should be investigated. Maybe, allow for a non-symmetric
1793 // rounding, like -16. 1798 // rounding, like -16.
1794 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; 1799 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN;
1795 int moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements); 1800 int moved_elements =
1796 WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements); 1801 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements);
1797 aec->knownDelay -= moved_elements * PART_LEN; 1802 aec->knownDelay -= moved_elements * PART_LEN;
1798 #ifdef WEBRTC_AEC_DEBUG_DUMP
1799 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1800 #endif
1801 } else { 1803 } else {
1802 // 2 b) Apply signal based delay correction. 1804 // 2 b) Apply signal based delay correction.
1803 int move_elements = SignalBasedDelayCorrection(aec); 1805 int move_elements = SignalBasedDelayCorrection(aec);
1804 int moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements); 1806 int moved_elements =
1805 WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements); 1807 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements);
1806 #ifdef WEBRTC_AEC_DEBUG_DUMP 1808 int far_near_buffer_diff = WebRtc_available_read(aec->far_buf) -
1807 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); 1809 WebRtc_available_read(aec->nearFrBuf) / PART_LEN;
1808 #endif
1809 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); 1810 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements);
1810 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, 1811 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend,
1811 moved_elements); 1812 moved_elements);
1812 aec->signal_delay_correction += moved_elements; 1813 aec->signal_delay_correction += moved_elements;
1813 // TODO(bjornv): Investigate if this is reasonable. I had to add this 1814 // If we rely on reported system delay values only, a buffer underrun here
1814 // guard when the signal based delay correction replaces the system based 1815 // can never occur since we've taken care of that in 1) above. Here, we
1815 // one. Otherwise there was a buffer underrun in the "qa-new/01/" 1816 // apply signal based delay correction and can therefore end up with
1816 // recording when adding 44 ms extra delay. This was not seen if we kept 1817 // buffer underruns since the delay estimation can be wrong. We therefore
1817 // both delay correction algorithms running in parallel. 1818 // stuff the buffer with enough elements if needed.
1818 // A first investigation showed that we have a drift in this case that 1819 if (far_near_buffer_diff < 0) {
1819 // causes the buffer underrun. Compared to when delay correction was 1820 WebRtcAec_MoveFarReadPtr(aec, far_near_buffer_diff);
1820 // turned off, we get buffer underrun as well which was triggered in 1)
1821 // above. In addition there was a shift in |knownDelay| later increasing
1822 // the buffer. When running in parallel, this if statement was not
1823 // triggered. This suggests two alternatives; (a) use both algorithms, or
1824 // (b) allow for smaller delay corrections when we operate close to the
1825 // buffer limit. At the time of testing we required a change of 6 blocks,
1826 // but could change it to, e.g., 2 blocks. It requires some testing
1827 // though.
1828 if ((int)WebRtc_available_read(aec->far_buf) < (aec->mult + 1)) {
1829 // We don't have enough data so we stuff the far-end buffers.
1830 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1));
1831 } 1821 }
1832 } 1822 }
1833 1823
1834 // 4) Process as many blocks as possible. 1824 // 4) Process as many blocks as possible.
1835 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) { 1825 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) {
1836 ProcessBlock(aec); 1826 ProcessBlock(aec);
1837 } 1827 }
1838 1828
1839 // 5) Update system delay with respect to the entire frame. 1829 // 5) Update system delay with respect to the entire frame.
1840 aec->system_delay -= FRAME_LEN; 1830 aec->system_delay -= FRAME_LEN;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1924 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1935 return self->extended_filter_enabled; 1925 return self->extended_filter_enabled;
1936 } 1926 }
1937 1927
1938 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1928 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; }
1939 1929
1940 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1930 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1941 assert(delay >= 0); 1931 assert(delay >= 0);
1942 self->system_delay = delay; 1932 self->system_delay = delay;
1943 } 1933 }
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/echo_cancellation.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698