| 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 |
| 11 /* | 11 /* |
| 12 * The core AEC algorithm, which is presented with time-aligned signals. | 12 * The core AEC algorithm, which is presented with time-aligned signals. |
| 13 */ | 13 */ |
| 14 | 14 |
| 15 #include "webrtc/modules/audio_processing/aec/aec_core.h" | 15 #include "webrtc/modules/audio_processing/aec/aec_core.h" |
| 16 | 16 |
| 17 #include <algorithm> | 17 #include <algorithm> |
| 18 #include <assert.h> | |
| 19 #include <math.h> | 18 #include <math.h> |
| 20 #include <stddef.h> // size_t | 19 #include <stddef.h> // size_t |
| 21 #include <stdlib.h> | 20 #include <stdlib.h> |
| 22 #include <string.h> | 21 #include <string.h> |
| 23 | 22 |
| 24 #include "webrtc/base/checks.h" | 23 #include "webrtc/base/checks.h" |
| 25 extern "C" { | 24 extern "C" { |
| 26 #include "webrtc/common_audio/ring_buffer.h" | 25 #include "webrtc/common_audio/ring_buffer.h" |
| 27 } | 26 } |
| 28 #include "webrtc/base/checks.h" | 27 #include "webrtc/base/checks.h" |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 freq_data[0][PART_LEN] = time_data[1]; | 862 freq_data[0][PART_LEN] = time_data[1]; |
| 864 for (i = 1; i < PART_LEN; i++) { | 863 for (i = 1; i < PART_LEN; i++) { |
| 865 freq_data[0][i] = time_data[2 * i]; | 864 freq_data[0][i] = time_data[2 * i]; |
| 866 freq_data[1][i] = time_data[2 * i + 1]; | 865 freq_data[1][i] = time_data[2 * i + 1]; |
| 867 } | 866 } |
| 868 } | 867 } |
| 869 | 868 |
| 870 static int SignalBasedDelayCorrection(AecCore* self) { | 869 static int SignalBasedDelayCorrection(AecCore* self) { |
| 871 int delay_correction = 0; | 870 int delay_correction = 0; |
| 872 int last_delay = -2; | 871 int last_delay = -2; |
| 873 assert(self != NULL); | 872 RTC_DCHECK(self); |
| 874 #if !defined(WEBRTC_ANDROID) | 873 #if !defined(WEBRTC_ANDROID) |
| 875 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This | 874 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This |
| 876 // is to let the delay estimation get a chance to converge. Also, if the | 875 // is to let the delay estimation get a chance to converge. Also, if the |
| 877 // playout audio volume is low (or even muted) the delay estimation can return | 876 // playout audio volume is low (or even muted) the delay estimation can return |
| 878 // a very large delay, which will break the AEC if it is applied. | 877 // a very large delay, which will break the AEC if it is applied. |
| 879 if (self->frame_count < kDelayCorrectionStart) { | 878 if (self->frame_count < kDelayCorrectionStart) { |
| 880 self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay); | 879 self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay); |
| 881 return 0; | 880 return 0; |
| 882 } | 881 } |
| 883 #endif | 882 #endif |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1839 // first relies on delay input values from the user and the amount of | 1838 // first relies on delay input values from the user and the amount of |
| 1840 // shifted buffer elements is controlled by |knownDelay|. This delay will | 1839 // shifted buffer elements is controlled by |knownDelay|. This delay will |
| 1841 // give a guess on how much we need to shift far-end buffers to align with | 1840 // give a guess on how much we need to shift far-end buffers to align with |
| 1842 // the near-end signal. The other delay estimation algorithm uses the | 1841 // the near-end signal. The other delay estimation algorithm uses the |
| 1843 // far- and near-end signals to find the offset between them. This one | 1842 // far- and near-end signals to find the offset between them. This one |
| 1844 // (called "signal delay") is then used to fine tune the alignment, or | 1843 // (called "signal delay") is then used to fine tune the alignment, or |
| 1845 // simply compensate for errors in the system based one. | 1844 // simply compensate for errors in the system based one. |
| 1846 // Note that the two algorithms operate independently. Currently, we only | 1845 // Note that the two algorithms operate independently. Currently, we only |
| 1847 // allow one algorithm to be turned on. | 1846 // allow one algorithm to be turned on. |
| 1848 | 1847 |
| 1849 assert(aec->num_bands == num_bands); | 1848 RTC_DCHECK_EQ(aec->num_bands, num_bands); |
| 1850 | 1849 |
| 1851 for (size_t j = 0; j < num_samples; j += FRAME_LEN) { | 1850 for (size_t j = 0; j < num_samples; j += FRAME_LEN) { |
| 1852 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we | 1851 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we |
| 1853 // have enough far-end data for that by stuffing the buffer if the | 1852 // have enough far-end data for that by stuffing the buffer if the |
| 1854 // |system_delay| indicates others. | 1853 // |system_delay| indicates others. |
| 1855 if (aec->system_delay < FRAME_LEN) { | 1854 if (aec->system_delay < FRAME_LEN) { |
| 1856 // We don't have enough data so we rewind 10 ms. | 1855 // We don't have enough data so we rewind 10 ms. |
| 1857 WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aec, -(aec->mult + 1)); | 1856 WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aec, -(aec->mult + 1)); |
| 1858 } | 1857 } |
| 1859 | 1858 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1942 // 6) Form the output frame. | 1941 // 6) Form the output frame. |
| 1943 FormOutputFrame(j, num_bands, &aec->output_buffer_size, aec->output_buffer, | 1942 FormOutputFrame(j, num_bands, &aec->output_buffer_size, aec->output_buffer, |
| 1944 out); | 1943 out); |
| 1945 } | 1944 } |
| 1946 } | 1945 } |
| 1947 | 1946 |
| 1948 int WebRtcAec_GetDelayMetricsCore(AecCore* self, | 1947 int WebRtcAec_GetDelayMetricsCore(AecCore* self, |
| 1949 int* median, | 1948 int* median, |
| 1950 int* std, | 1949 int* std, |
| 1951 float* fraction_poor_delays) { | 1950 float* fraction_poor_delays) { |
| 1952 assert(self != NULL); | 1951 RTC_DCHECK(self); |
| 1953 assert(median != NULL); | 1952 RTC_DCHECK(median); |
| 1954 assert(std != NULL); | 1953 RTC_DCHECK(std); |
| 1955 | 1954 |
| 1956 if (self->delay_logging_enabled == 0) { | 1955 if (self->delay_logging_enabled == 0) { |
| 1957 // Logging disabled. | 1956 // Logging disabled. |
| 1958 return -1; | 1957 return -1; |
| 1959 } | 1958 } |
| 1960 | 1959 |
| 1961 if (self->delay_metrics_delivered == 0) { | 1960 if (self->delay_metrics_delivered == 0) { |
| 1962 UpdateDelayMetrics(self); | 1961 UpdateDelayMetrics(self); |
| 1963 self->delay_metrics_delivered = 1; | 1962 self->delay_metrics_delivered = 1; |
| 1964 } | 1963 } |
| 1965 *median = self->delay_median; | 1964 *median = self->delay_median; |
| 1966 *std = self->delay_std; | 1965 *std = self->delay_std; |
| 1967 *fraction_poor_delays = self->fraction_poor_delays; | 1966 *fraction_poor_delays = self->fraction_poor_delays; |
| 1968 | 1967 |
| 1969 return 0; | 1968 return 0; |
| 1970 } | 1969 } |
| 1971 | 1970 |
| 1972 int WebRtcAec_echo_state(AecCore* self) { | 1971 int WebRtcAec_echo_state(AecCore* self) { |
| 1973 return self->echoState; | 1972 return self->echoState; |
| 1974 } | 1973 } |
| 1975 | 1974 |
| 1976 void WebRtcAec_GetEchoStats(AecCore* self, | 1975 void WebRtcAec_GetEchoStats(AecCore* self, |
| 1977 Stats* erl, | 1976 Stats* erl, |
| 1978 Stats* erle, | 1977 Stats* erle, |
| 1979 Stats* a_nlp, | 1978 Stats* a_nlp, |
| 1980 float* divergent_filter_fraction) { | 1979 float* divergent_filter_fraction) { |
| 1981 assert(erl != NULL); | 1980 RTC_DCHECK(erl); |
| 1982 assert(erle != NULL); | 1981 RTC_DCHECK(erle); |
| 1983 assert(a_nlp != NULL); | 1982 RTC_DCHECK(a_nlp); |
| 1984 *erl = self->erl; | 1983 *erl = self->erl; |
| 1985 *erle = self->erle; | 1984 *erle = self->erle; |
| 1986 *a_nlp = self->aNlp; | 1985 *a_nlp = self->aNlp; |
| 1987 *divergent_filter_fraction = | 1986 *divergent_filter_fraction = |
| 1988 self->divergent_filter_fraction.GetLatestFraction(); | 1987 self->divergent_filter_fraction.GetLatestFraction(); |
| 1989 } | 1988 } |
| 1990 | 1989 |
| 1991 void WebRtcAec_SetConfigCore(AecCore* self, | 1990 void WebRtcAec_SetConfigCore(AecCore* self, |
| 1992 int nlp_mode, | 1991 int nlp_mode, |
| 1993 int metrics_mode, | 1992 int metrics_mode, |
| 1994 int delay_logging) { | 1993 int delay_logging) { |
| 1995 assert(nlp_mode >= 0 && nlp_mode < 3); | 1994 RTC_DCHECK_GE(nlp_mode, 0); |
| 1995 RTC_DCHECK_LT(nlp_mode, 3); |
| 1996 self->nlp_mode = nlp_mode; | 1996 self->nlp_mode = nlp_mode; |
| 1997 self->metricsMode = metrics_mode; | 1997 self->metricsMode = metrics_mode; |
| 1998 if (self->metricsMode) { | 1998 if (self->metricsMode) { |
| 1999 InitMetrics(self); | 1999 InitMetrics(self); |
| 2000 } | 2000 } |
| 2001 // Turn on delay logging if it is either set explicitly or if delay agnostic | 2001 // Turn on delay logging if it is either set explicitly or if delay agnostic |
| 2002 // AEC is enabled (which requires delay estimates). | 2002 // AEC is enabled (which requires delay estimates). |
| 2003 self->delay_logging_enabled = delay_logging || self->delay_agnostic_enabled; | 2003 self->delay_logging_enabled = delay_logging || self->delay_agnostic_enabled; |
| 2004 if (self->delay_logging_enabled) { | 2004 if (self->delay_logging_enabled) { |
| 2005 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); | 2005 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); |
| 2006 } | 2006 } |
| 2007 } | 2007 } |
| 2008 | 2008 |
| 2009 void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable) { | 2009 void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable) { |
| 2010 self->delay_agnostic_enabled = enable; | 2010 self->delay_agnostic_enabled = enable; |
| 2011 } | 2011 } |
| 2012 | 2012 |
| 2013 int WebRtcAec_delay_agnostic_enabled(AecCore* self) { | 2013 int WebRtcAec_delay_agnostic_enabled(AecCore* self) { |
| 2014 return self->delay_agnostic_enabled; | 2014 return self->delay_agnostic_enabled; |
| 2015 } | 2015 } |
| 2016 | 2016 |
| 2017 void WebRtcAec_enable_aec3(AecCore* self, int enable) { | 2017 void WebRtcAec_enable_aec3(AecCore* self, int enable) { |
| 2018 self->aec3_enabled = (enable != 0); | 2018 self->aec3_enabled = (enable != 0); |
| 2019 } | 2019 } |
| 2020 | 2020 |
| 2021 int WebRtcAec_aec3_enabled(AecCore* self) { | 2021 int WebRtcAec_aec3_enabled(AecCore* self) { |
| 2022 assert(self->aec3_enabled == 0 || self->aec3_enabled == 1); | 2022 RTC_DCHECK(self->aec3_enabled == 0 || self->aec3_enabled == 1); |
| 2023 return self->aec3_enabled; | 2023 return self->aec3_enabled; |
| 2024 } | 2024 } |
| 2025 | 2025 |
| 2026 void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) { | 2026 void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) { |
| 2027 self->refined_adaptive_filter_enabled = enable; | 2027 self->refined_adaptive_filter_enabled = enable; |
| 2028 SetAdaptiveFilterStepSize(self); | 2028 SetAdaptiveFilterStepSize(self); |
| 2029 SetErrorThreshold(self); | 2029 SetErrorThreshold(self); |
| 2030 } | 2030 } |
| 2031 | 2031 |
| 2032 bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) { | 2032 bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2044 | 2044 |
| 2045 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 2045 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
| 2046 return self->extended_filter_enabled; | 2046 return self->extended_filter_enabled; |
| 2047 } | 2047 } |
| 2048 | 2048 |
| 2049 int WebRtcAec_system_delay(AecCore* self) { | 2049 int WebRtcAec_system_delay(AecCore* self) { |
| 2050 return self->system_delay; | 2050 return self->system_delay; |
| 2051 } | 2051 } |
| 2052 | 2052 |
| 2053 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 2053 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 2054 assert(delay >= 0); | 2054 RTC_DCHECK_GE(delay, 0); |
| 2055 self->system_delay = delay; | 2055 self->system_delay = delay; |
| 2056 } | 2056 } |
| 2057 } // namespace webrtc | 2057 } // namespace webrtc |
| OLD | NEW |