| 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 |