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