diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn index 6baf3a1ddb..a9026f8735 100644 --- a/modules/audio_processing/aec3/BUILD.gn +++ b/modules/audio_processing/aec3/BUILD.gn @@ -84,8 +84,6 @@ rtc_static_library("aec3") { "render_delay_controller.h", "render_delay_controller_metrics.cc", "render_delay_controller_metrics.h", - "render_reverb_model.cc", - "render_reverb_model.h", "render_signal_analyzer.cc", "render_signal_analyzer.h", "residual_echo_estimator.cc", diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc index f0e183aa57..bd6710ab25 100644 --- a/modules/audio_processing/aec3/aec_state.cc +++ b/modules/audio_processing/aec3/aec_state.cc @@ -29,6 +29,56 @@ namespace { constexpr size_t kBlocksSinceConvergencedFilterInit = 10000; constexpr size_t kBlocksSinceConsistentEstimateInit = 10000; +void UpdateAndComputeReverb( + const SpectrumBuffer& spectrum_buffer, + int delay_blocks, + float reverb_decay, + ReverbModel* reverb_model, + rtc::ArrayView reverb_power_spectrum) { + RTC_DCHECK(reverb_model); + const size_t num_render_channels = spectrum_buffer.buffer[0].size(); + int idx_at_delay = + spectrum_buffer.OffsetIndex(spectrum_buffer.read, delay_blocks); + int idx_past = spectrum_buffer.IncIndex(idx_at_delay); + + std::array X2_data; + rtc::ArrayView X2; + if (num_render_channels > 1) { + auto sum_channels = + [](size_t num_render_channels, + const std::vector>& spectrum_band_0, + rtc::ArrayView render_power) { + std::fill(render_power.begin(), render_power.end(), 0.f); + for (size_t ch = 0; ch < num_render_channels; ++ch) { + RTC_DCHECK_EQ(spectrum_band_0[ch].size(), kFftLengthBy2Plus1); + for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) { + render_power[k] += spectrum_band_0[ch][k]; + } + } + }; + sum_channels(num_render_channels, spectrum_buffer.buffer[idx_past], + X2_data); + reverb_model->UpdateReverbNoFreqShaping( + X2_data, /*power_spectrum_scaling=*/1.0f, reverb_decay); + + sum_channels(num_render_channels, spectrum_buffer.buffer[idx_at_delay], + X2_data); + X2 = X2_data; + } else { + reverb_model->UpdateReverbNoFreqShaping( + spectrum_buffer.buffer[idx_past][/*channel=*/0], + /*power_spectrum_scaling=*/1.0f, reverb_decay); + + X2 = spectrum_buffer.buffer[idx_at_delay][/*channel=*/0]; + } + + rtc::ArrayView reverb_power = + reverb_model->reverb(); + for (size_t k = 0; k < X2.size(); ++k) { + reverb_power_spectrum[k] = X2[k] + reverb_power[k]; + } +} + } // namespace int AecState::instance_count_ = 0; @@ -171,14 +221,14 @@ void AecState::Update( active_render && !SaturatedCapture() ? 1 : 0; std::array X2_reverb; - render_reverb_.Apply(render_buffer.GetSpectrumBuffer(), - delay_state_.DirectPathFilterDelay(), ReverbDecay(), - X2_reverb); + + UpdateAndComputeReverb(render_buffer.GetSpectrumBuffer(), + delay_state_.DirectPathFilterDelay(), ReverbDecay(), + &reverb_model_, X2_reverb); if (config_.echo_audibility.use_stationarity_properties) { // Update the echo audibility evaluator. - echo_audibility_.Update(render_buffer, - render_reverb_.GetReverbContributionPowerSpectrum(), + echo_audibility_.Update(render_buffer, reverb_model_.reverb(), delay_state_.DirectPathFilterDelay(), delay_state_.ExternalDelayReported()); } diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h index 500822dc40..69cdafd9c9 100644 --- a/modules/audio_processing/aec3/aec_state.h +++ b/modules/audio_processing/aec3/aec_state.h @@ -28,7 +28,6 @@ #include "modules/audio_processing/aec3/erle_estimator.h" #include "modules/audio_processing/aec3/filter_analyzer.h" #include "modules/audio_processing/aec3/render_buffer.h" -#include "modules/audio_processing/aec3/render_reverb_model.h" #include "modules/audio_processing/aec3/reverb_model_estimator.h" #include "modules/audio_processing/aec3/subtractor_output.h" #include "modules/audio_processing/aec3/subtractor_output_analyzer.h" @@ -294,7 +293,7 @@ class AecState { absl::optional external_delay_; EchoAudibility echo_audibility_; ReverbModelEstimator reverb_model_estimator_; - RenderReverbModel render_reverb_; + ReverbModel reverb_model_; std::vector subtractor_output_analyzers_; }; diff --git a/modules/audio_processing/aec3/render_reverb_model.cc b/modules/audio_processing/aec3/render_reverb_model.cc deleted file mode 100644 index 0410a9a1ad..0000000000 --- a/modules/audio_processing/aec3/render_reverb_model.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/audio_processing/aec3/render_reverb_model.h" - -#include - -#include "api/array_view.h" -#include "rtc_base/checks.h" - -namespace webrtc { - -RenderReverbModel::RenderReverbModel() { - Reset(); -} - -RenderReverbModel::~RenderReverbModel() = default; - -void RenderReverbModel::Reset() { - render_reverb_.Reset(); -} - -void RenderReverbModel::Apply(const SpectrumBuffer& spectrum_buffer, - int delay_blocks, - float reverb_decay, - rtc::ArrayView reverb_power_spectrum) { - int idx_at_delay = - spectrum_buffer.OffsetIndex(spectrum_buffer.read, delay_blocks); - int idx_past = spectrum_buffer.IncIndex(idx_at_delay); - const auto& X2 = spectrum_buffer.buffer[idx_at_delay][/*channel=*/0]; - RTC_DCHECK_EQ(X2.size(), reverb_power_spectrum.size()); - render_reverb_.UpdateReverbNoFreqShaping( - spectrum_buffer.buffer[idx_past][/*channel=*/0], 1.0f, reverb_decay); - - rtc::ArrayView reverb_power = - render_reverb_.reverb(); - for (size_t k = 0; k < X2.size(); ++k) { - reverb_power_spectrum[k] = X2[k] + reverb_power[k]; - } -} - -} // namespace webrtc diff --git a/modules/audio_processing/aec3/render_reverb_model.h b/modules/audio_processing/aec3/render_reverb_model.h deleted file mode 100644 index 8859a907ab..0000000000 --- a/modules/audio_processing/aec3/render_reverb_model.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef MODULES_AUDIO_PROCESSING_AEC3_RENDER_REVERB_MODEL_H_ -#define MODULES_AUDIO_PROCESSING_AEC3_RENDER_REVERB_MODEL_H_ - -#include "api/array_view.h" -#include "modules/audio_processing/aec3/reverb_model.h" -#include "modules/audio_processing/aec3/spectrum_buffer.h" - -namespace webrtc { - -// The RenderReverbModel class applies an exponential reverberant model over the -// render spectrum. -class RenderReverbModel { - public: - RenderReverbModel(); - ~RenderReverbModel(); - - // Resets the state. - void Reset(); - - // Applies the reverberation model over the render spectrum. It also returns - // the reverberation render power spectrum in the array reverb_power_spectrum. - void Apply(const SpectrumBuffer& spectrum_buffer, - int delay_blocks, - float reverb_decay, - rtc::ArrayView reverb_power_spectrum); - - // Gets the reverberation spectrum that was added to the render spectrum for - // computing the reverberation render spectrum. - rtc::ArrayView GetReverbContributionPowerSpectrum() const { - return render_reverb_.reverb(); - } - - private: - ReverbModel render_reverb_; -}; - -} // namespace webrtc. - -#endif // MODULES_AUDIO_PROCESSING_AEC3_RENDER_REVERB_MODEL_H_