Chromium Code Reviews| Index: webrtc/modules/audio_processing/aec/aec_core.cc |
| diff --git a/webrtc/modules/audio_processing/aec/aec_core.cc b/webrtc/modules/audio_processing/aec/aec_core.cc |
| index 4b5abedd5aa7694172fe773438fcc0822dc08ee9..5fbe05cdf0485e7c21ade7dee83de12856a8f108 100644 |
| --- a/webrtc/modules/audio_processing/aec/aec_core.cc |
| +++ b/webrtc/modules/audio_processing/aec/aec_core.cc |
| @@ -25,6 +25,7 @@ |
| #include <stdlib.h> |
| #include <string.h> |
| +#include "webrtc/base/checks.h" |
| extern "C" { |
| #include "webrtc/common_audio/ring_buffer.h" |
| } |
| @@ -239,11 +240,10 @@ static void FilterFar(int num_partitions, |
| } |
| static void ScaleErrorSignal(int extended_filter_enabled, |
|
tlegrand-webrtc
2016/04/14 14:32:42
This function don't really need the first paramete
peah-webrtc
2016/04/14 22:12:41
That is definitely a good change. I did not want t
tlegrand-webrtc
2016/04/15 09:07:04
Great! I think it's fine, since the CL isn't that
|
| - float normal_mu, |
| + float mu, |
|
tlegrand-webrtc
2016/04/14 14:32:42
With removal of mu = kExtendedMu if extended filte
hlundin-webrtc
2016/04/14 14:47:46
It is now called (through EchoSubtraction) with ae
peah-webrtc
2016/04/14 22:12:41
Fully true.
peah-webrtc
2016/04/14 22:12:41
It is now called in a different way but with a mu
tlegrand-webrtc
2016/04/15 09:07:04
Acknowledged.
|
| float normal_error_threshold, |
| float x_pow[PART_LEN1], |
| float ef[2][PART_LEN1]) { |
| - const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; |
| const float error_threshold = extended_filter_enabled |
| ? kExtendedErrorThreshold |
| : normal_error_threshold; |
| @@ -936,10 +936,36 @@ static int SignalBasedDelayCorrection(AecCore* self) { |
| return delay_correction; |
| } |
| +static void RegressorPower(int num_partitions, |
| + int latest_added_partition, |
| + float x_fft_buf[2] |
| + [kExtendedNumPartitions * PART_LEN1], |
| + float x_pow[PART_LEN1]) { |
| + RTC_DCHECK_LT(latest_added_partition, num_partitions); |
| + memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0])); |
| + |
| + int partition = latest_added_partition; |
| + int x_fft_buf_position = partition * PART_LEN1; |
| + for (int i = 0; i < num_partitions; ++i) { |
| + for (int bin = 0; bin < PART_LEN1; ++bin) { |
| + float re = x_fft_buf[0][x_fft_buf_position]; |
| + float im = x_fft_buf[1][x_fft_buf_position]; |
| + x_pow[bin] += re * re + im * im; |
| + ++x_fft_buf_position; |
| + } |
| + |
| + ++partition; |
| + if (partition == num_partitions) { |
| + partition = 0; |
| + x_fft_buf_position = 0; |
|
hlundin-webrtc
2016/04/14 14:02:26
Can you DCHECK what you expect x_fft_buf_position
peah-webrtc
2016/04/14 22:12:41
Good point!
Done.
|
| + } |
| + } |
| +} |
| + |
| static void EchoSubtraction(AecCore* aec, |
| int num_partitions, |
| int extended_filter_enabled, |
| - float normal_mu, |
| + float filter_step_size, |
| float normal_error_threshold, |
| float* x_fft, |
| int* x_fft_buf_block_pos, |
| @@ -1001,7 +1027,7 @@ static void EchoSubtraction(AecCore* aec, |
| sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
| // Scale error signal inversely with far power. |
| - WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, |
| + WebRtcAec_ScaleErrorSignal(extended_filter_enabled, filter_step_size, |
| normal_error_threshold, x_pow, e_fft); |
| WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
| e_fft, h_fft_buf); |
| @@ -1316,14 +1342,27 @@ static void ProcessBlock(AecCore* aec) { |
| Fft(fft, df); |
| // Power smoothing |
| - for (i = 0; i < PART_LEN1; i++) { |
| - far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| - (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| - aec->xPow[i] = |
| - gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; |
| - // Calculate absolute spectra |
| - abs_far_spectrum[i] = sqrtf(far_spectrum); |
| + if (aec->refined_adaptive_filter_enabled) { |
| + for (i = 0; i < PART_LEN1; ++i) { |
| + far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| + (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| + // Calculate absolute spectra |
| + abs_far_spectrum[i] = sqrtf(far_spectrum); |
| + } |
| + RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf, |
| + aec->xPow); |
| + } else { |
| + for (i = 0; i < PART_LEN1; ++i) { |
| + far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| + (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| + aec->xPow[i] = |
| + gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; |
| + // Calculate absolute spectra |
| + abs_far_spectrum[i] = sqrtf(far_spectrum); |
| + } |
| + } |
| + for (i = 0; i < PART_LEN1; ++i) { |
| near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; |
| aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; |
| // Calculate absolute spectra |
| @@ -1379,9 +1418,9 @@ static void ProcessBlock(AecCore* aec) { |
| // Perform echo subtraction. |
| EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, |
| - aec->normal_mu, aec->normal_error_threshold, &x_fft[0][0], |
| - &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, |
| - aec->wfBuf, echo_subtractor_output); |
| + aec->filter_step_size, aec->normal_error_threshold, |
| + &x_fft[0][0], &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, |
| + aec->xPow, aec->wfBuf, echo_subtractor_output); |
| RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
| @@ -1485,6 +1524,7 @@ AecCore* WebRtcAec_CreateAec() { |
| #endif |
| aec->extended_filter_enabled = 0; |
| aec->aec3_enabled = 0; |
| + aec->refined_adaptive_filter_enabled = false; |
| // Assembly optimization |
| WebRtcAec_FilterFar = FilterFar; |
| @@ -1548,17 +1588,37 @@ void WebRtcAec_FreeAec(AecCore* aec) { |
| delete aec; |
| } |
| +static void SetAdaptiveFilterStepSize(AecCore* aec) { |
| + // Extended filter adaptation parameter. |
| + // TODO(ajm): No narrowband tuning yet. |
| + const float kExtendedMu = 0.4f; |
| + |
| + if (aec->refined_adaptive_filter_enabled) { |
| + aec->filter_step_size = 0.05f; |
|
hlundin-webrtc
2016/04/14 14:02:26
The old code seems to vary the step size depending
peah-webrtc
2016/04/14 22:12:41
Maybe,
The only way the sample rate affects the a
|
| + } else { |
| + if (aec->extended_filter_enabled) { |
| + aec->filter_step_size = kExtendedMu; |
| + } else { |
| + if (aec->sampFreq == 8000) { |
| + aec->filter_step_size = 0.6f; |
| + } else { |
| + aec->filter_step_size = 0.5f; |
| + } |
| + } |
| + } |
| +} |
| + |
| int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { |
| int i; |
| aec->sampFreq = sampFreq; |
| + SetAdaptiveFilterStepSize(aec); |
| + |
| if (sampFreq == 8000) { |
| - aec->normal_mu = 0.6f; |
| aec->normal_error_threshold = 2e-6f; |
| aec->num_bands = 1; |
| } else { |
| - aec->normal_mu = 0.5f; |
| aec->normal_error_threshold = 1.5e-6f; |
| aec->num_bands = (size_t)(sampFreq / 16000); |
| } |
| @@ -1930,6 +1990,14 @@ int WebRtcAec_aec3_enabled(AecCore* self) { |
| return self->aec3_enabled; |
| } |
| +void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) { |
| + self->refined_adaptive_filter_enabled = enable; |
| + SetAdaptiveFilterStepSize(self); |
| +} |
| + |
| +bool WebRtcAec_refined_adaptive_filter_enabled(AecCore* self) { |
|
hlundin-webrtc
2016/04/14 14:02:27
const AecCore*
peah-webrtc
2016/04/14 22:12:41
Done.
|
| + return self->refined_adaptive_filter_enabled; |
| +} |
| void WebRtcAec_enable_extended_filter(AecCore* self, int enable) { |
| self->extended_filter_enabled = enable; |