| 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 | |
| 868 static int SignalBasedDelayCorrection(AecCore* self) { | 860 static int SignalBasedDelayCorrection(AecCore* self) { |
| 869 int delay_correction = 0; | 861 int delay_correction = 0; |
| 870 int last_delay = -2; | 862 int last_delay = -2; |
| 871 assert(self != NULL); | 863 assert(self != NULL); |
| 872 #if !defined(WEBRTC_ANDROID) | 864 #if !defined(WEBRTC_ANDROID) |
| 873 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This | 865 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This |
| 874 // is to let the delay estimation get a chance to converge. Also, if the | 866 // is to let the delay estimation get a chance to converge. Also, if the |
| 875 // playout audio volume is low (or even muted) the delay estimation can return | 867 // playout audio volume is low (or even muted) the delay estimation can return |
| 876 // a very large delay, which will break the AEC if it is applied. | 868 // a very large delay, which will break the AEC if it is applied. |
| 877 if (self->frame_count < kDelayCorrectionStart) { | 869 if (self->frame_count < kDelayCorrectionStart) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 898 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); | 890 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); |
| 899 // Allow for a slack in the actual delay, defined by a |lower_bound| and an | 891 // Allow for a slack in the actual delay, defined by a |lower_bound| and an |
| 900 // |upper_bound|. The adaptive echo cancellation filter is currently | 892 // |upper_bound|. The adaptive echo cancellation filter is currently |
| 901 // |num_partitions| (of 64 samples) long. If the delay estimate is negative | 893 // |num_partitions| (of 64 samples) long. If the delay estimate is negative |
| 902 // or at least 3/4 of the filter length we open up for correction. | 894 // or at least 3/4 of the filter length we open up for correction. |
| 903 const int lower_bound = 0; | 895 const int lower_bound = 0; |
| 904 const int upper_bound = self->num_partitions * 3 / 4; | 896 const int upper_bound = self->num_partitions * 3 / 4; |
| 905 const int do_correction = delay <= lower_bound || delay > upper_bound; | 897 const int do_correction = delay <= lower_bound || delay > upper_bound; |
| 906 if (do_correction == 1) { | 898 if (do_correction == 1) { |
| 907 int available_read = (int)WebRtc_available_read(self->far_buf); | 899 int available_read = (int)WebRtc_available_read(self->far_buf); |
| 908 // With |shift_offset| we gradually rely on the delay estimates. For | 900 // Adjust w.r.t. a |shift_offset| to account for not as reliable estimates |
| 909 // positive delays we reduce the correction by |shift_offset| to lower the | 901 // in the beginning, hence we are more conservative. |
| 910 // risk of pushing the AEC into a non causal state. For negative delays | 902 delay_correction = -(delay - self->shift_offset); |
| 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; | |
| 915 self->shift_offset--; | 903 self->shift_offset--; |
| 916 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); | 904 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); |
| 917 if (delay_correction > available_read - self->mult - 1) { | 905 if (delay_correction > available_read - self->mult - 1) { |
| 918 // There is not enough data in the buffer to perform this shift. Hence, | 906 // There is not enough data in the buffer to perform this shift. Hence, |
| 919 // we do not rely on the delay estimate and do nothing. | 907 // we do not rely on the delay estimate and do nothing. |
| 920 delay_correction = 0; | 908 delay_correction = 0; |
| 921 } else { | 909 } else { |
| 922 self->previous_delay = last_delay; | 910 self->previous_delay = last_delay; |
| 923 ++self->delay_correction_count; | 911 ++self->delay_correction_count; |
| 924 } | 912 } |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1720 TimeToFrequency(fft, xf, 0); | 1708 TimeToFrequency(fft, xf, 0); |
| 1721 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); | 1709 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); |
| 1722 | 1710 |
| 1723 // Convert far-end partition to the frequency domain with windowing. | 1711 // Convert far-end partition to the frequency domain with windowing. |
| 1724 memcpy(fft, farend, sizeof(float) * PART_LEN2); | 1712 memcpy(fft, farend, sizeof(float) * PART_LEN2); |
| 1725 TimeToFrequency(fft, xf, 1); | 1713 TimeToFrequency(fft, xf, 1); |
| 1726 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); | 1714 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); |
| 1727 } | 1715 } |
| 1728 | 1716 |
| 1729 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { | 1717 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { |
| 1730 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements); | 1718 int elements_moved = WebRtc_MoveReadPtr(aec->far_buf_windowed, elements); |
| 1719 WebRtc_MoveReadPtr(aec->far_buf, elements); |
| 1720 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 1721 WebRtc_MoveReadPtr(aec->far_time_buf, elements); |
| 1722 #endif |
| 1731 aec->system_delay -= elements_moved * PART_LEN; | 1723 aec->system_delay -= elements_moved * PART_LEN; |
| 1732 return elements_moved; | 1724 return elements_moved; |
| 1733 } | 1725 } |
| 1734 | 1726 |
| 1735 void WebRtcAec_ProcessFrames(AecCore* aec, | 1727 void WebRtcAec_ProcessFrames(AecCore* aec, |
| 1736 const float* const* nearend, | 1728 const float* const* nearend, |
| 1737 int num_bands, | 1729 int num_bands, |
| 1738 int num_samples, | 1730 int num_samples, |
| 1739 int knownDelay, | 1731 int knownDelay, |
| 1740 float* const* out) { | 1732 float* const* out) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1793 // 2 a) Compensate for a possible change in the system delay. | 1785 // 2 a) Compensate for a possible change in the system delay. |
| 1794 | 1786 |
| 1795 // TODO(bjornv): Investigate how we should round the delay difference; | 1787 // TODO(bjornv): Investigate how we should round the delay difference; |
| 1796 // right now we know that incoming |knownDelay| is underestimated when | 1788 // right now we know that incoming |knownDelay| is underestimated when |
| 1797 // it's less than |aec->knownDelay|. We therefore, round (-32) in that | 1789 // it's less than |aec->knownDelay|. We therefore, round (-32) in that |
| 1798 // direction. In the other direction, we don't have this situation, but | 1790 // direction. In the other direction, we don't have this situation, but |
| 1799 // might flush one partition too little. This can cause non-causality, | 1791 // might flush one partition too little. This can cause non-causality, |
| 1800 // which should be investigated. Maybe, allow for a non-symmetric | 1792 // which should be investigated. Maybe, allow for a non-symmetric |
| 1801 // rounding, like -16. | 1793 // rounding, like -16. |
| 1802 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; | 1794 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; |
| 1803 int moved_elements = | 1795 int moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements); |
| 1804 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); | 1796 WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements); |
| 1805 aec->knownDelay -= moved_elements * PART_LEN; | 1797 aec->knownDelay -= moved_elements * PART_LEN; |
| 1798 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 1799 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
| 1800 #endif |
| 1806 } else { | 1801 } else { |
| 1807 // 2 b) Apply signal based delay correction. | 1802 // 2 b) Apply signal based delay correction. |
| 1808 int move_elements = SignalBasedDelayCorrection(aec); | 1803 int move_elements = SignalBasedDelayCorrection(aec); |
| 1809 int moved_elements = | 1804 int moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements); |
| 1810 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); | 1805 WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements); |
| 1811 int far_near_buffer_diff = WebRtc_available_read(aec->far_buf) - | 1806 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 1812 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; | 1807 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
| 1808 #endif |
| 1813 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); | 1809 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); |
| 1814 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, | 1810 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, |
| 1815 moved_elements); | 1811 moved_elements); |
| 1816 aec->signal_delay_correction += moved_elements; | 1812 aec->signal_delay_correction += moved_elements; |
| 1817 // If we rely on reported system delay values only, a buffer underrun here | 1813 // TODO(bjornv): Investigate if this is reasonable. I had to add this |
| 1818 // can never occur since we've taken care of that in 1) above. Here, we | 1814 // guard when the signal based delay correction replaces the system based |
| 1819 // apply signal based delay correction and can therefore end up with | 1815 // one. Otherwise there was a buffer underrun in the "qa-new/01/" |
| 1820 // buffer underruns since the delay estimation can be wrong. We therefore | 1816 // recording when adding 44 ms extra delay. This was not seen if we kept |
| 1821 // stuff the buffer with enough elements if needed. | 1817 // both delay correction algorithms running in parallel. |
| 1822 if (far_near_buffer_diff < 0) { | 1818 // A first investigation showed that we have a drift in this case that |
| 1823 WebRtcAec_MoveFarReadPtr(aec, far_near_buffer_diff); | 1819 // causes the buffer underrun. Compared to when delay correction was |
| 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)); |
| 1824 } | 1831 } |
| 1825 } | 1832 } |
| 1826 | 1833 |
| 1827 // 4) Process as many blocks as possible. | 1834 // 4) Process as many blocks as possible. |
| 1828 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) { | 1835 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) { |
| 1829 ProcessBlock(aec); | 1836 ProcessBlock(aec); |
| 1830 } | 1837 } |
| 1831 | 1838 |
| 1832 // 5) Update system delay with respect to the entire frame. | 1839 // 5) Update system delay with respect to the entire frame. |
| 1833 aec->system_delay -= FRAME_LEN; | 1840 aec->system_delay -= FRAME_LEN; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1934 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
| 1928 return self->extended_filter_enabled; | 1935 return self->extended_filter_enabled; |
| 1929 } | 1936 } |
| 1930 | 1937 |
| 1931 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1938 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
| 1932 | 1939 |
| 1933 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1940 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1934 assert(delay >= 0); | 1941 assert(delay >= 0); |
| 1935 self->system_delay = delay; | 1942 self->system_delay = delay; |
| 1936 } | 1943 } |
| OLD | NEW |