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 |