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 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 freq_data[0][PART_LEN] = time_data[1]; | 812 freq_data[0][PART_LEN] = time_data[1]; |
814 for (i = 1; i < PART_LEN; i++) { | 813 for (i = 1; i < PART_LEN; i++) { |
815 freq_data[0][i] = time_data[2 * i]; | 814 freq_data[0][i] = time_data[2 * i]; |
816 freq_data[1][i] = time_data[2 * i + 1]; | 815 freq_data[1][i] = time_data[2 * i + 1]; |
817 } | 816 } |
818 } | 817 } |
819 | 818 |
820 static int SignalBasedDelayCorrection(AecCore* self) { | 819 static int SignalBasedDelayCorrection(AecCore* self) { |
821 int delay_correction = 0; | 820 int delay_correction = 0; |
822 int last_delay = -2; | 821 int last_delay = -2; |
823 assert(self != NULL); | 822 RTC_DCHECK(self); |
824 #if !defined(WEBRTC_ANDROID) | 823 #if !defined(WEBRTC_ANDROID) |
825 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This | 824 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This |
826 // is to let the delay estimation get a chance to converge. Also, if the | 825 // is to let the delay estimation get a chance to converge. Also, if the |
827 // playout audio volume is low (or even muted) the delay estimation can return | 826 // playout audio volume is low (or even muted) the delay estimation can return |
828 // a very large delay, which will break the AEC if it is applied. | 827 // a very large delay, which will break the AEC if it is applied. |
829 if (self->frame_count < kDelayCorrectionStart) { | 828 if (self->frame_count < kDelayCorrectionStart) { |
830 self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay); | 829 self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay); |
831 return 0; | 830 return 0; |
832 } | 831 } |
833 #endif | 832 #endif |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 float output[PART_LEN]; | 1267 float output[PART_LEN]; |
1269 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1268 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1270 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1269 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
1271 float* x_fft_ptr = NULL; | 1270 float* x_fft_ptr = NULL; |
1272 | 1271 |
1273 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1272 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1274 outputH_ptr[i] = outputH[i]; | 1273 outputH_ptr[i] = outputH[i]; |
1275 } | 1274 } |
1276 | 1275 |
1277 // We should always have at least one element stored in |far_buf|. | 1276 // We should always have at least one element stored in |far_buf|. |
1278 assert(WebRtc_available_read(aec->far_time_buf) > 0); | 1277 RTC_DCHECK_GT(WebRtc_available_read(aec->far_time_buf), 0u); |
1279 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr), | 1278 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr), |
1280 farend, 1); | 1279 farend, 1); |
1281 | 1280 |
1282 aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN], | 1281 aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN], |
1283 std::min(aec->sampFreq, 16000), 1); | 1282 std::min(aec->sampFreq, 16000), 1); |
1284 aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0], | 1283 aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0], |
1285 std::min(aec->sampFreq, 16000), 1); | 1284 std::min(aec->sampFreq, 16000), 1); |
1286 | 1285 |
1287 if (aec->metricsMode == 1) { | 1286 if (aec->metricsMode == 1) { |
1288 // Update power levels | 1287 // Update power levels |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 // first relies on delay input values from the user and the amount of | 1770 // first relies on delay input values from the user and the amount of |
1772 // shifted buffer elements is controlled by |knownDelay|. This delay will | 1771 // shifted buffer elements is controlled by |knownDelay|. This delay will |
1773 // give a guess on how much we need to shift far-end buffers to align with | 1772 // give a guess on how much we need to shift far-end buffers to align with |
1774 // the near-end signal. The other delay estimation algorithm uses the | 1773 // the near-end signal. The other delay estimation algorithm uses the |
1775 // far- and near-end signals to find the offset between them. This one | 1774 // far- and near-end signals to find the offset between them. This one |
1776 // (called "signal delay") is then used to fine tune the alignment, or | 1775 // (called "signal delay") is then used to fine tune the alignment, or |
1777 // simply compensate for errors in the system based one. | 1776 // simply compensate for errors in the system based one. |
1778 // Note that the two algorithms operate independently. Currently, we only | 1777 // Note that the two algorithms operate independently. Currently, we only |
1779 // allow one algorithm to be turned on. | 1778 // allow one algorithm to be turned on. |
1780 | 1779 |
1781 assert(aec->num_bands == num_bands); | 1780 RTC_DCHECK_EQ(aec->num_bands, num_bands); |
1782 | 1781 |
1783 for (size_t j = 0; j < num_samples; j += FRAME_LEN) { | 1782 for (size_t j = 0; j < num_samples; j += FRAME_LEN) { |
1784 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we | 1783 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we |
1785 // have enough far-end data for that by stuffing the buffer if the | 1784 // have enough far-end data for that by stuffing the buffer if the |
1786 // |system_delay| indicates others. | 1785 // |system_delay| indicates others. |
1787 if (aec->system_delay < FRAME_LEN) { | 1786 if (aec->system_delay < FRAME_LEN) { |
1788 // We don't have enough data so we rewind 10 ms. | 1787 // We don't have enough data so we rewind 10 ms. |
1789 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); | 1788 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); |
1790 } | 1789 } |
1791 | 1790 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 for (size_t i = 1; i < num_bands; ++i) { | 1876 for (size_t i = 1; i < num_bands; ++i) { |
1878 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); | 1877 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); |
1879 } | 1878 } |
1880 } | 1879 } |
1881 } | 1880 } |
1882 | 1881 |
1883 int WebRtcAec_GetDelayMetricsCore(AecCore* self, | 1882 int WebRtcAec_GetDelayMetricsCore(AecCore* self, |
1884 int* median, | 1883 int* median, |
1885 int* std, | 1884 int* std, |
1886 float* fraction_poor_delays) { | 1885 float* fraction_poor_delays) { |
1887 assert(self != NULL); | 1886 RTC_DCHECK(self); |
1888 assert(median != NULL); | 1887 RTC_DCHECK(median); |
1889 assert(std != NULL); | 1888 RTC_DCHECK(std); |
1890 | 1889 |
1891 if (self->delay_logging_enabled == 0) { | 1890 if (self->delay_logging_enabled == 0) { |
1892 // Logging disabled. | 1891 // Logging disabled. |
1893 return -1; | 1892 return -1; |
1894 } | 1893 } |
1895 | 1894 |
1896 if (self->delay_metrics_delivered == 0) { | 1895 if (self->delay_metrics_delivered == 0) { |
1897 UpdateDelayMetrics(self); | 1896 UpdateDelayMetrics(self); |
1898 self->delay_metrics_delivered = 1; | 1897 self->delay_metrics_delivered = 1; |
1899 } | 1898 } |
1900 *median = self->delay_median; | 1899 *median = self->delay_median; |
1901 *std = self->delay_std; | 1900 *std = self->delay_std; |
1902 *fraction_poor_delays = self->fraction_poor_delays; | 1901 *fraction_poor_delays = self->fraction_poor_delays; |
1903 | 1902 |
1904 return 0; | 1903 return 0; |
1905 } | 1904 } |
1906 | 1905 |
1907 int WebRtcAec_echo_state(AecCore* self) { | 1906 int WebRtcAec_echo_state(AecCore* self) { |
1908 return self->echoState; | 1907 return self->echoState; |
1909 } | 1908 } |
1910 | 1909 |
1911 void WebRtcAec_GetEchoStats(AecCore* self, | 1910 void WebRtcAec_GetEchoStats(AecCore* self, |
1912 Stats* erl, | 1911 Stats* erl, |
1913 Stats* erle, | 1912 Stats* erle, |
1914 Stats* a_nlp, | 1913 Stats* a_nlp, |
1915 float* divergent_filter_fraction) { | 1914 float* divergent_filter_fraction) { |
1916 assert(erl != NULL); | 1915 RTC_DCHECK(erl); |
1917 assert(erle != NULL); | 1916 RTC_DCHECK(erle); |
1918 assert(a_nlp != NULL); | 1917 RTC_DCHECK(a_nlp); |
1919 *erl = self->erl; | 1918 *erl = self->erl; |
1920 *erle = self->erle; | 1919 *erle = self->erle; |
1921 *a_nlp = self->aNlp; | 1920 *a_nlp = self->aNlp; |
1922 *divergent_filter_fraction = | 1921 *divergent_filter_fraction = |
1923 self->divergent_filter_fraction.GetLatestFraction(); | 1922 self->divergent_filter_fraction.GetLatestFraction(); |
1924 } | 1923 } |
1925 | 1924 |
1926 void WebRtcAec_SetConfigCore(AecCore* self, | 1925 void WebRtcAec_SetConfigCore(AecCore* self, |
1927 int nlp_mode, | 1926 int nlp_mode, |
1928 int metrics_mode, | 1927 int metrics_mode, |
1929 int delay_logging) { | 1928 int delay_logging) { |
1930 assert(nlp_mode >= 0 && nlp_mode < 3); | 1929 RTC_DCHECK_GE(nlp_mode, 0); |
| 1930 RTC_DCHECK_LT(nlp_mode, 3); |
1931 self->nlp_mode = nlp_mode; | 1931 self->nlp_mode = nlp_mode; |
1932 self->metricsMode = metrics_mode; | 1932 self->metricsMode = metrics_mode; |
1933 if (self->metricsMode) { | 1933 if (self->metricsMode) { |
1934 InitMetrics(self); | 1934 InitMetrics(self); |
1935 } | 1935 } |
1936 // Turn on delay logging if it is either set explicitly or if delay agnostic | 1936 // Turn on delay logging if it is either set explicitly or if delay agnostic |
1937 // AEC is enabled (which requires delay estimates). | 1937 // AEC is enabled (which requires delay estimates). |
1938 self->delay_logging_enabled = delay_logging || self->delay_agnostic_enabled; | 1938 self->delay_logging_enabled = delay_logging || self->delay_agnostic_enabled; |
1939 if (self->delay_logging_enabled) { | 1939 if (self->delay_logging_enabled) { |
1940 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); | 1940 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); |
1941 } | 1941 } |
1942 } | 1942 } |
1943 | 1943 |
1944 void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable) { | 1944 void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable) { |
1945 self->delay_agnostic_enabled = enable; | 1945 self->delay_agnostic_enabled = enable; |
1946 } | 1946 } |
1947 | 1947 |
1948 int WebRtcAec_delay_agnostic_enabled(AecCore* self) { | 1948 int WebRtcAec_delay_agnostic_enabled(AecCore* self) { |
1949 return self->delay_agnostic_enabled; | 1949 return self->delay_agnostic_enabled; |
1950 } | 1950 } |
1951 | 1951 |
1952 void WebRtcAec_enable_aec3(AecCore* self, int enable) { | 1952 void WebRtcAec_enable_aec3(AecCore* self, int enable) { |
1953 self->aec3_enabled = (enable != 0); | 1953 self->aec3_enabled = (enable != 0); |
1954 } | 1954 } |
1955 | 1955 |
1956 int WebRtcAec_aec3_enabled(AecCore* self) { | 1956 int WebRtcAec_aec3_enabled(AecCore* self) { |
1957 assert(self->aec3_enabled == 0 || self->aec3_enabled == 1); | 1957 RTC_DCHECK(self->aec3_enabled == 0 || self->aec3_enabled == 1); |
1958 return self->aec3_enabled; | 1958 return self->aec3_enabled; |
1959 } | 1959 } |
1960 | 1960 |
1961 void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) { | 1961 void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) { |
1962 self->refined_adaptive_filter_enabled = enable; | 1962 self->refined_adaptive_filter_enabled = enable; |
1963 SetAdaptiveFilterStepSize(self); | 1963 SetAdaptiveFilterStepSize(self); |
1964 SetErrorThreshold(self); | 1964 SetErrorThreshold(self); |
1965 } | 1965 } |
1966 | 1966 |
1967 bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) { | 1967 bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) { |
(...skipping 11 matching lines...) Expand all Loading... |
1979 | 1979 |
1980 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1980 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1981 return self->extended_filter_enabled; | 1981 return self->extended_filter_enabled; |
1982 } | 1982 } |
1983 | 1983 |
1984 int WebRtcAec_system_delay(AecCore* self) { | 1984 int WebRtcAec_system_delay(AecCore* self) { |
1985 return self->system_delay; | 1985 return self->system_delay; |
1986 } | 1986 } |
1987 | 1987 |
1988 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1988 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1989 assert(delay >= 0); | 1989 RTC_DCHECK_GE(delay, 0); |
1990 self->system_delay = delay; | 1990 self->system_delay = delay; |
1991 } | 1991 } |
1992 } // namespace webrtc | 1992 } // namespace webrtc |
OLD | NEW |