diff --git a/api/audio/echo_canceller3_factory.cc b/api/audio/echo_canceller3_factory.cc index 07f295f2ea..e83e552270 100644 --- a/api/audio/echo_canceller3_factory.cc +++ b/api/audio/echo_canceller3_factory.cc @@ -22,6 +22,6 @@ EchoCanceller3Factory::EchoCanceller3Factory(const EchoCanceller3Config& config) : config_(config) {} std::unique_ptr EchoCanceller3Factory::Create(int sample_rate_hz) { - return absl::make_unique(config_, sample_rate_hz, true); + return absl::make_unique(config_, sample_rate_hz); } } // namespace webrtc diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index e4df10b7ec..c8a9dbc383 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -87,6 +87,24 @@ rtc_static_library("audio_buffer") { ] } +rtc_static_library("high_pass_filter") { + visibility = [ "*" ] + + sources = [ + "high_pass_filter.cc", + "high_pass_filter.h", + ] + + defines = [] + + deps = [ + ":audio_buffer", + "../../api:array_view", + "../../rtc_base:checks", + "utility:cascaded_biquad_filter", + ] +} + rtc_static_library("audio_processing") { visibility = [ "*" ] configs += [ ":apm_debug_dump" ] @@ -116,8 +134,6 @@ rtc_static_library("audio_processing") { "include/aec_dump.h", "level_estimator_impl.cc", "level_estimator_impl.h", - "low_cut_filter.cc", - "low_cut_filter.h", "noise_suppression_impl.cc", "noise_suppression_impl.h", "render_queue_item_verifier.h", @@ -156,6 +172,7 @@ rtc_static_library("audio_processing") { ":config", ":gain_control_config_proxy", ":gain_control_interface", + ":high_pass_filter", ":noise_suppression_proxy", "../../api:array_view", "../../api:function_view", @@ -384,6 +401,7 @@ if (rtc_include_tests) { ] deps = [ ":api", + ":audio_buffer", ":audio_processing", ":audio_processing_statistics", "../../test:test_support", @@ -445,6 +463,7 @@ if (rtc_include_tests) { ":config", ":file_audio_generator_unittests", ":gain_control_config_proxy", + ":high_pass_filter", ":mocks", "../../api:array_view", "../../api:scoped_refptr", @@ -522,8 +541,8 @@ if (rtc_include_tests) { "echo_detector/moving_max_unittest.cc", "echo_detector/normalized_covariance_estimator_unittest.cc", "gain_control_unittest.cc", + "high_pass_filter_unittest.cc", "level_estimator_unittest.cc", - "low_cut_filter_unittest.cc", "noise_suppression_unittest.cc", "residual_echo_detector_unittest.cc", "rms_level_unittest.cc", diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn index 50eef88d37..61c6f1edf5 100644 --- a/modules/audio_processing/aec3/BUILD.gn +++ b/modules/audio_processing/aec3/BUILD.gn @@ -30,8 +30,6 @@ rtc_static_library("aec3") { "block_processor.h", "block_processor_metrics.cc", "block_processor_metrics.h", - "cascaded_biquad_filter.cc", - "cascaded_biquad_filter.h", "clockdrift_detector.cc", "clockdrift_detector.h", "comfort_noise_generator.cc", @@ -130,6 +128,7 @@ rtc_static_library("aec3") { deps = [ "..:apm_logging", "..:audio_buffer", + "..:high_pass_filter", "../../../api:array_view", "../../../api/audio:aec3_config", "../../../api/audio:echo_control", @@ -141,6 +140,7 @@ rtc_static_library("aec3") { "../../../system_wrappers:cpu_features_api", "../../../system_wrappers:field_trial", "../../../system_wrappers:metrics", + "../utility:cascaded_biquad_filter", "../utility:ooura_fft", "//third_party/abseil-cpp/absl/types:optional", ] @@ -168,6 +168,7 @@ if (rtc_include_tests) { "..:audio_buffer", "..:audio_processing", "..:audio_processing_unittests", + "..:high_pass_filter", "../../../api:array_view", "../../../api/audio:aec3_config", "../../../rtc_base:checks", @@ -176,6 +177,7 @@ if (rtc_include_tests) { "../../../rtc_base/system:arch", "../../../system_wrappers:cpu_features_api", "../../../test:test_support", + "../utility:cascaded_biquad_filter", "//third_party/abseil-cpp/absl/types:optional", ] @@ -191,7 +193,6 @@ if (rtc_include_tests) { "block_framer_unittest.cc", "block_processor_metrics_unittest.cc", "block_processor_unittest.cc", - "cascaded_biquad_filter_unittest.cc", "clockdrift_detector_unittest.cc", "comfort_noise_generator_unittest.cc", "decimator_unittest.cc", diff --git a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc index 2eff6a17ec..821573639e 100644 --- a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc +++ b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc @@ -24,12 +24,12 @@ #include "modules/audio_processing/aec3/aec3_fft.h" #include "modules/audio_processing/aec3/aec_state.h" -#include "modules/audio_processing/aec3/cascaded_biquad_filter.h" #include "modules/audio_processing/aec3/render_delay_buffer.h" #include "modules/audio_processing/aec3/render_signal_analyzer.h" #include "modules/audio_processing/aec3/shadow_filter_update_gain.h" #include "modules/audio_processing/logging/apm_data_dumper.h" #include "modules/audio_processing/test/echo_canceller_test_tools.h" +#include "modules/audio_processing/utility/cascaded_biquad_filter.h" #include "rtc_base/arraysize.h" #include "rtc_base/numerics/safe_minmax.h" #include "rtc_base/random.h" diff --git a/modules/audio_processing/aec3/decimator.h b/modules/audio_processing/aec3/decimator.h index a5050143c4..9dd6b19473 100644 --- a/modules/audio_processing/aec3/decimator.h +++ b/modules/audio_processing/aec3/decimator.h @@ -15,7 +15,7 @@ #include "api/array_view.h" #include "modules/audio_processing/aec3/aec3_common.h" -#include "modules/audio_processing/aec3/cascaded_biquad_filter.h" +#include "modules/audio_processing/utility/cascaded_biquad_filter.h" #include "rtc_base/constructor_magic.h" namespace webrtc { diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc index 952f5e73de..c2ad56b83d 100644 --- a/modules/audio_processing/aec3/echo_canceller3.cc +++ b/modules/audio_processing/aec3/echo_canceller3.cc @@ -13,6 +13,7 @@ #include #include "modules/audio_processing/aec3/aec3_common.h" +#include "modules/audio_processing/high_pass_filter.h" #include "modules/audio_processing/logging/apm_data_dumper.h" #include "rtc_base/atomic_ops.h" #include "system_wrappers/include/field_trial.h" @@ -124,31 +125,19 @@ void BufferRemainingRenderFrameContent(FrameBlocker* render_blocker, block_processor->BufferRender(*block); } -void CopyBufferIntoFrame(AudioBuffer* buffer, +void CopyBufferIntoFrame(const AudioBuffer& buffer, size_t num_bands, size_t frame_length, std::vector>* frame) { RTC_DCHECK_EQ(num_bands, frame->size()); RTC_DCHECK_EQ(frame_length, (*frame)[0].size()); for (size_t k = 0; k < num_bands; ++k) { - rtc::ArrayView buffer_view(&buffer->split_bands(0)[k][0], - frame_length); + rtc::ArrayView buffer_view(&buffer.split_bands_const(0)[k][0], + frame_length); std::copy(buffer_view.begin(), buffer_view.end(), (*frame)[k].begin()); } } -// [B,A] = butter(2,100/4000,'high') -const CascadedBiQuadFilter::BiQuadCoefficients - kHighPassFilterCoefficients_8kHz = {{0.94598f, -1.89195f, 0.94598f}, - {-1.88903f, 0.89487f}}; -const int kNumberOfHighPassBiQuads_8kHz = 1; - -// [B,A] = butter(2,100/8000,'high') -const CascadedBiQuadFilter::BiQuadCoefficients - kHighPassFilterCoefficients_16kHz = {{0.97261f, -1.94523f, 0.97261f}, - {-1.94448f, 0.94598f}}; -const int kNumberOfHighPassBiQuads_16kHz = 1; - } // namespace class EchoCanceller3::RenderWriter { @@ -156,19 +145,18 @@ class EchoCanceller3::RenderWriter { RenderWriter(ApmDataDumper* data_dumper, SwapQueue>, Aec3RenderQueueItemVerifier>* render_transfer_queue, - std::unique_ptr render_highpass_filter, int sample_rate_hz, int frame_length, int num_bands); ~RenderWriter(); - void Insert(AudioBuffer* input); + void Insert(const AudioBuffer& input); private: ApmDataDumper* data_dumper_; const int sample_rate_hz_; const size_t frame_length_; const int num_bands_; - std::unique_ptr render_highpass_filter_; + HighPassFilter high_pass_filter_; std::vector> render_queue_input_frame_; SwapQueue>, Aec3RenderQueueItemVerifier>* render_transfer_queue_; @@ -179,7 +167,6 @@ EchoCanceller3::RenderWriter::RenderWriter( ApmDataDumper* data_dumper, SwapQueue>, Aec3RenderQueueItemVerifier>* render_transfer_queue, - std::unique_ptr render_highpass_filter, int sample_rate_hz, int frame_length, int num_bands) @@ -187,7 +174,7 @@ EchoCanceller3::RenderWriter::RenderWriter( sample_rate_hz_(sample_rate_hz), frame_length_(frame_length), num_bands_(num_bands), - render_highpass_filter_(std::move(render_highpass_filter)), + high_pass_filter_(1), render_queue_input_frame_(num_bands_, std::vector(frame_length_, 0.f)), render_transfer_queue_(render_transfer_queue) { @@ -196,25 +183,23 @@ EchoCanceller3::RenderWriter::RenderWriter( EchoCanceller3::RenderWriter::~RenderWriter() = default; -void EchoCanceller3::RenderWriter::Insert(AudioBuffer* input) { - RTC_DCHECK_EQ(1, input->num_channels()); - RTC_DCHECK_EQ(frame_length_, input->num_frames_per_band()); - RTC_DCHECK_EQ(num_bands_, input->num_bands()); +void EchoCanceller3::RenderWriter::Insert(const AudioBuffer& input) { + RTC_DCHECK_EQ(1, input.num_channels()); + RTC_DCHECK_EQ(frame_length_, input.num_frames_per_band()); + RTC_DCHECK_EQ(num_bands_, input.num_bands()); // TODO(bugs.webrtc.org/8759) Temporary work-around. - if (num_bands_ != static_cast(input->num_bands())) + if (num_bands_ != static_cast(input.num_bands())) return; data_dumper_->DumpWav("aec3_render_input", frame_length_, - &input->split_bands(0)[0][0], + &input.split_bands_const(0)[0][0], LowestBandRate(sample_rate_hz_), 1); CopyBufferIntoFrame(input, num_bands_, frame_length_, &render_queue_input_frame_); - if (render_highpass_filter_) { - render_highpass_filter_->Process(render_queue_input_frame_[0]); - } + high_pass_filter_.Process(render_queue_input_frame_[0]); static_cast(render_transfer_queue_->Insert(&render_queue_input_frame_)); } @@ -222,17 +207,14 @@ void EchoCanceller3::RenderWriter::Insert(AudioBuffer* input) { int EchoCanceller3::instance_count_ = 0; EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config, - int sample_rate_hz, - bool use_highpass_filter) + int sample_rate_hz) : EchoCanceller3( AdjustConfig(config), sample_rate_hz, - use_highpass_filter, std::unique_ptr( BlockProcessor::Create(AdjustConfig(config), sample_rate_hz))) {} EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config, int sample_rate_hz, - bool use_highpass_filter, std::unique_ptr block_processor) : data_dumper_( new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), @@ -259,24 +241,9 @@ EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config, config_.delay.fixed_capture_delay_samples) { RTC_DCHECK(ValidFullBandRate(sample_rate_hz_)); - std::unique_ptr render_highpass_filter; - if (use_highpass_filter) { - render_highpass_filter.reset(new CascadedBiQuadFilter( - sample_rate_hz_ == 8000 ? kHighPassFilterCoefficients_8kHz - : kHighPassFilterCoefficients_16kHz, - sample_rate_hz_ == 8000 ? kNumberOfHighPassBiQuads_8kHz - : kNumberOfHighPassBiQuads_16kHz)); - capture_highpass_filter_.reset(new CascadedBiQuadFilter( - sample_rate_hz_ == 8000 ? kHighPassFilterCoefficients_8kHz - : kHighPassFilterCoefficients_16kHz, - sample_rate_hz_ == 8000 ? kNumberOfHighPassBiQuads_8kHz - : kNumberOfHighPassBiQuads_16kHz)); - } - render_writer_.reset( new RenderWriter(data_dumper_.get(), &render_transfer_queue_, - std::move(render_highpass_filter), sample_rate_hz_, - frame_length_, num_bands_)); + sample_rate_hz_, frame_length_, num_bands_)); RTC_DCHECK_EQ(num_bands_, std::max(sample_rate_hz_, 16000) / 16000); RTC_DCHECK_GE(kMaxNumBands, num_bands_); @@ -284,26 +251,24 @@ EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config, EchoCanceller3::~EchoCanceller3() = default; -void EchoCanceller3::AnalyzeRender(AudioBuffer* render) { +void EchoCanceller3::AnalyzeRender(const AudioBuffer& render) { RTC_DCHECK_RUNS_SERIALIZED(&render_race_checker_); - RTC_DCHECK(render); data_dumper_->DumpRaw("aec3_call_order", static_cast(EchoCanceller3ApiCall::kRender)); return render_writer_->Insert(render); } -void EchoCanceller3::AnalyzeCapture(AudioBuffer* capture) { +void EchoCanceller3::AnalyzeCapture(const AudioBuffer& capture) { RTC_DCHECK_RUNS_SERIALIZED(&capture_race_checker_); - RTC_DCHECK(capture); - data_dumper_->DumpWav("aec3_capture_analyze_input", capture->num_frames(), - capture->channels()[0], sample_rate_hz_, 1); + data_dumper_->DumpWav("aec3_capture_analyze_input", capture.num_frames(), + capture.channels_const()[0], sample_rate_hz_, 1); saturated_microphone_signal_ = false; - for (size_t k = 0; k < capture->num_channels(); ++k) { + for (size_t k = 0; k < capture.num_channels(); ++k) { saturated_microphone_signal_ |= - DetectSaturation(rtc::ArrayView(capture->channels()[k], - capture->num_frames())); + DetectSaturation(rtc::ArrayView( + capture.channels_const()[k], capture.num_frames())); if (saturated_microphone_signal_) { break; } @@ -336,10 +301,6 @@ void EchoCanceller3::ProcessCapture(AudioBuffer* capture, bool level_change) { EmptyRenderQueue(); - if (capture_highpass_filter_) { - capture_highpass_filter_->Process(capture_lower_band); - } - ProcessCaptureFrameContent( capture, level_change, saturated_microphone_signal_, 0, &capture_blocker_, &output_framer_, block_processor_.get(), &block_, &sub_frame_view_); diff --git a/modules/audio_processing/aec3/echo_canceller3.h b/modules/audio_processing/aec3/echo_canceller3.h index 2782687dd4..d7dea80136 100644 --- a/modules/audio_processing/aec3/echo_canceller3.h +++ b/modules/audio_processing/aec3/echo_canceller3.h @@ -23,7 +23,6 @@ #include "modules/audio_processing/aec3/block_delay_buffer.h" #include "modules/audio_processing/aec3/block_framer.h" #include "modules/audio_processing/aec3/block_processor.h" -#include "modules/audio_processing/aec3/cascaded_biquad_filter.h" #include "modules/audio_processing/aec3/frame_blocker.h" #include "modules/audio_processing/audio_buffer.h" #include "modules/audio_processing/logging/apm_data_dumper.h" @@ -74,20 +73,19 @@ class Aec3RenderQueueItemVerifier { class EchoCanceller3 : public EchoControl { public: // Normal c-tor to use. - EchoCanceller3(const EchoCanceller3Config& config, - int sample_rate_hz, - bool use_highpass_filter); + EchoCanceller3(const EchoCanceller3Config& config, int sample_rate_hz); // Testing c-tor that is used only for testing purposes. EchoCanceller3(const EchoCanceller3Config& config, int sample_rate_hz, - bool use_highpass_filter, std::unique_ptr block_processor); ~EchoCanceller3() override; // Analyzes and stores an internal copy of the split-band domain render // signal. - void AnalyzeRender(AudioBuffer* farend) override; + void AnalyzeRender(AudioBuffer* render) override { AnalyzeRender(*render); } // Analyzes the full-band domain capture signal to detect signal saturation. - void AnalyzeCapture(AudioBuffer* capture) override; + void AnalyzeCapture(AudioBuffer* capture) override { + AnalyzeCapture(*capture); + } // Processes the split-band domain capture signal in order to remove any echo // present in the signal. void ProcessCapture(AudioBuffer* capture, bool level_change) override; @@ -111,6 +109,12 @@ class EchoCanceller3 : public EchoControl { // Empties the render SwapQueue. void EmptyRenderQueue(); + // Analyzes and stores an internal copy of the split-band domain render + // signal. + void AnalyzeRender(const AudioBuffer& render); + // Analyzes the full-band domain capture signal to detect signal saturation. + void AnalyzeCapture(const AudioBuffer& capture); + rtc::RaceChecker capture_race_checker_; rtc::RaceChecker render_race_checker_; @@ -134,8 +138,6 @@ class EchoCanceller3 : public EchoControl { RTC_GUARDED_BY(capture_race_checker_); std::vector> render_queue_output_frame_ RTC_GUARDED_BY(capture_race_checker_); - std::unique_ptr capture_highpass_filter_ - RTC_GUARDED_BY(capture_race_checker_); bool saturated_microphone_signal_ RTC_GUARDED_BY(capture_race_checker_) = false; std::vector> block_ RTC_GUARDED_BY(capture_race_checker_); diff --git a/modules/audio_processing/aec3/echo_canceller3_unittest.cc b/modules/audio_processing/aec3/echo_canceller3_unittest.cc index 1b6bdaf7aa..a29b779348 100644 --- a/modules/audio_processing/aec3/echo_canceller3_unittest.cc +++ b/modules/audio_processing/aec3/echo_canceller3_unittest.cc @@ -21,6 +21,8 @@ #include "modules/audio_processing/aec3/frame_blocker.h" #include "modules/audio_processing/aec3/mock/mock_block_processor.h" #include "modules/audio_processing/audio_buffer.h" +#include "modules/audio_processing/high_pass_filter.h" +#include "modules/audio_processing/utility/cascaded_biquad_filter.h" #include "rtc_base/strings/string_builder.h" #include "test/gmock.h" #include "test/gtest.h" @@ -85,6 +87,20 @@ bool VerifyOutputFrameBitexactness(size_t frame_length, return true; } +bool VerifyOutputFrameBitexactness(rtc::ArrayView reference, + rtc::ArrayView frame, + int offset) { + for (size_t k = 0; k < frame.size(); ++k) { + int reference_index = static_cast(k) + offset; + if (reference_index >= 0) { + if (reference[reference_index] != frame[k]) { + return false; + } + } + } + return true; +} + // Class for testing that the capture data is properly received by the block // processor and that the processor data is properly passed to the // EchoCanceller3 output. @@ -166,7 +182,7 @@ class EchoCanceller3Tester { // output. void RunCaptureTransportVerificationTest() { EchoCanceller3 aec3( - EchoCanceller3Config(), sample_rate_hz_, false, + EchoCanceller3Config(), sample_rate_hz_, std::unique_ptr( new CaptureTransportVerificationProcessor(num_bands_))); @@ -191,10 +207,12 @@ class EchoCanceller3Tester { // block processor. void RunRenderTransportVerificationTest() { EchoCanceller3 aec3( - EchoCanceller3Config(), sample_rate_hz_, false, + EchoCanceller3Config(), sample_rate_hz_, std::unique_ptr( new RenderTransportVerificationProcessor(num_bands_))); + std::vector render_input; + std::vector capture_output; for (size_t frame_index = 0; frame_index < kNumFramesToProcess; ++frame_index) { aec3.AnalyzeCapture(&capture_buffer_); @@ -204,12 +222,20 @@ class EchoCanceller3Tester { PopulateInputFrame(frame_length_, num_bands_, frame_index, &render_buffer_.split_bands(0)[0], 0); + for (size_t k = 0; k < frame_length_; ++k) { + render_input.push_back(render_buffer_.split_bands(0)[0][k]); + } aec3.AnalyzeRender(&render_buffer_); aec3.ProcessCapture(&capture_buffer_, false); - EXPECT_TRUE(VerifyOutputFrameBitexactness( - frame_length_, num_bands_, frame_index, - &capture_buffer_.split_bands(0)[0], -64)); + for (size_t k = 0; k < frame_length_; ++k) { + capture_output.push_back(capture_buffer_.split_bands(0)[0][k]); + } } + HighPassFilter hp_filter(1); + hp_filter.Process(render_input); + + EXPECT_TRUE( + VerifyOutputFrameBitexactness(render_input, capture_output, -64)); } // Verifies that information about echo path changes are properly propagated @@ -255,7 +281,7 @@ class EchoCanceller3Tester { break; } - EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, false, + EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, std::move(block_processor_mock)); for (size_t frame_index = 0; frame_index < kNumFramesToProcess; @@ -337,7 +363,7 @@ class EchoCanceller3Tester { } break; } - EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, false, + EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, std::move(block_processor_mock)); for (size_t frame_index = 0; frame_index < kNumFramesToProcess; @@ -426,7 +452,7 @@ class EchoCanceller3Tester { } break; } - EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, false, + EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, std::move(block_processor_mock)); for (size_t frame_index = 0; frame_index < kNumFramesToProcess; ++frame_index) { @@ -466,10 +492,13 @@ class EchoCanceller3Tester { void RunRenderSwapQueueVerificationTest() { const EchoCanceller3Config config; EchoCanceller3 aec3( - config, sample_rate_hz_, false, + config, sample_rate_hz_, std::unique_ptr( new RenderTransportVerificationProcessor(num_bands_))); + std::vector render_input; + std::vector capture_output; + for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames; ++frame_index) { if (sample_rate_hz_ > 16000) { @@ -482,6 +511,9 @@ class EchoCanceller3Tester { render_buffer_.SplitIntoFrequencyBands(); } + for (size_t k = 0; k < frame_length_; ++k) { + render_input.push_back(render_buffer_.split_bands(0)[0][k]); + } aec3.AnalyzeRender(&render_buffer_); } @@ -496,16 +528,21 @@ class EchoCanceller3Tester { &capture_buffer_.split_bands(0)[0], 0); aec3.ProcessCapture(&capture_buffer_, false); - EXPECT_TRUE(VerifyOutputFrameBitexactness( - frame_length_, num_bands_, frame_index, - &capture_buffer_.split_bands(0)[0], -64)); + for (size_t k = 0; k < frame_length_; ++k) { + capture_output.push_back(capture_buffer_.split_bands(0)[0][k]); + } } + HighPassFilter hp_filter(1); + hp_filter.Process(render_input); + + EXPECT_TRUE( + VerifyOutputFrameBitexactness(render_input, capture_output, -64)); } // This test verifies that a buffer overrun in the render swapqueue is // properly reported. void RunRenderPipelineSwapQueueOverrunReturnValueTest() { - EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, false); + EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_); constexpr size_t kRenderTransferQueueSize = 30; for (size_t k = 0; k < 2; ++k) { @@ -517,11 +554,7 @@ class EchoCanceller3Tester { PopulateInputFrame(frame_length_, frame_index, &render_buffer_.channels()[0][0], 0); - if (k == 0) { - aec3.AnalyzeRender(&render_buffer_); - } else { - aec3.AnalyzeRender(&render_buffer_); - } + aec3.AnalyzeRender(&render_buffer_); } } } @@ -534,7 +567,7 @@ class EchoCanceller3Tester { // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a // way that the number of bands for the rates are different. const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000; - EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false); + EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz); PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0); EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), ""); @@ -547,7 +580,7 @@ class EchoCanceller3Tester { // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a // way that the number of bands for the rates are different. const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000; - EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false); + EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz); PopulateInputFrame(frame_length_, num_bands_, 0, &capture_buffer_.split_bands_f(0)[0], 100); EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), ""); @@ -560,7 +593,7 @@ class EchoCanceller3Tester { // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a // way that the band frame lengths are different. const int aec3_sample_rate_hz = sample_rate_hz_ == 8000 ? 16000 : 8000; - EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false); + EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz); OptionalBandSplit(); PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0); @@ -575,7 +608,7 @@ class EchoCanceller3Tester { // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a // way that the band frame lengths are different. const int aec3_sample_rate_hz = sample_rate_hz_ == 8000 ? 16000 : 8000; - EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, false); + EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz); OptionalBandSplit(); PopulateInputFrame(frame_length_, num_bands_, 0, @@ -713,26 +746,10 @@ TEST(EchoCanceller3InputCheck, WrongCaptureFrameLengthCheckVerification) { } } -// Verifiers that the verification for null input to the render analysis api -// call works. -TEST(EchoCanceller3InputCheck, NullRenderAnalysisParameter) { - EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8000, false) - .AnalyzeRender(nullptr), - ""); -} - -// Verifiers that the verification for null input to the capture analysis api -// call works. -TEST(EchoCanceller3InputCheck, NullCaptureAnalysisParameter) { - EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8000, false) - .AnalyzeCapture(nullptr), - ""); -} - // Verifiers that the verification for null input to the capture processing api // call works. TEST(EchoCanceller3InputCheck, NullCaptureProcessingParameter) { - EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8000, false) + EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 16000) .ProcessCapture(nullptr, false), ""); } @@ -742,7 +759,7 @@ TEST(EchoCanceller3InputCheck, NullCaptureProcessingParameter) { // tests on test bots has been fixed. TEST(EchoCanceller3InputCheck, DISABLED_WrongSampleRate) { ApmDataDumper data_dumper(0); - EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8001, false), ""); + EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8001), ""); } #endif diff --git a/modules/audio_processing/audio_buffer.h b/modules/audio_processing/audio_buffer.h index b6a41e2332..2d136d8aa6 100644 --- a/modules/audio_processing/audio_buffer.h +++ b/modules/audio_processing/audio_buffer.h @@ -32,6 +32,7 @@ enum Band { kBand0To8kHz = 0, kBand8To16kHz = 1, kBand16To24kHz = 2 }; // operate on it in a controlled manner. class AudioBuffer { public: + static const int kSplitBandSize = 160; AudioBuffer(size_t input_rate, size_t input_num_channels, size_t buffer_rate, diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 97babf99c8..bc61b523b9 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -32,10 +32,10 @@ #include "modules/audio_processing/gain_control_for_experimental_agc.h" #include "modules/audio_processing/gain_control_impl.h" #include "modules/audio_processing/gain_controller2.h" +#include "modules/audio_processing/high_pass_filter.h" #include "modules/audio_processing/include/audio_frame_view.h" #include "modules/audio_processing/level_estimator_impl.h" #include "modules/audio_processing/logging/apm_data_dumper.h" -#include "modules/audio_processing/low_cut_filter.h" #include "modules/audio_processing/noise_suppression_impl.h" #include "modules/audio_processing/noise_suppression_proxy.h" #include "modules/audio_processing/residual_echo_detector.h" @@ -252,7 +252,8 @@ bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandProcessingActive() return false; } -bool AudioProcessingImpl::ApmSubmoduleStates::LowCutFilteringRequired() const { +bool AudioProcessingImpl::ApmSubmoduleStates::HighPassFilteringRequired() + const { return high_pass_filter_enabled_ || echo_canceller_enabled_ || mobile_echo_controller_enabled_ || noise_suppressor_enabled_; } @@ -287,7 +288,7 @@ struct AudioProcessingImpl::ApmPrivateSubmodules { // Accessed internally from capture or during initialization std::unique_ptr agc_manager; std::unique_ptr gain_controller2; - std::unique_ptr low_cut_filter; + std::unique_ptr high_pass_filter; rtc::scoped_refptr echo_detector; std::unique_ptr echo_cancellation; std::unique_ptr echo_controller; @@ -547,7 +548,7 @@ int AudioProcessingImpl::InitializeLocked() { public_submodules_->gain_control_for_experimental_agc->Initialize(); } InitializeTransient(); - InitializeLowCutFilter(); + InitializeHighPassFilter(); public_submodules_->noise_suppression->Initialize(num_proc_channels(), proc_sample_rate_hz()); public_submodules_->voice_detection->Initialize(proc_split_sample_rate_hz()); @@ -694,7 +695,7 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) { public_submodules_->noise_suppression->set_level( NsConfigLevelToInterfaceLevel(config.noise_suppression.level)); - InitializeLowCutFilter(); + InitializeHighPassFilter(); RTC_LOG(LS_INFO) << "Highpass filter activated: " << config_.high_pass_filter.enabled; @@ -1348,10 +1349,8 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() { capture_buffer->set_num_channels(1); } - // TODO(peah): Move the AEC3 low-cut filter to this place. - if (private_submodules_->low_cut_filter && - !private_submodules_->echo_controller) { - private_submodules_->low_cut_filter->Process(capture_buffer); + if (private_submodules_->high_pass_filter) { + private_submodules_->high_pass_filter->Process(capture_buffer); } RETURN_ON_ERR( public_submodules_->gain_control->AnalyzeCaptureAudio(capture_buffer)); @@ -1828,12 +1827,12 @@ void AudioProcessingImpl::InitializeTransient() { } } -void AudioProcessingImpl::InitializeLowCutFilter() { - if (submodule_states_.LowCutFilteringRequired()) { - private_submodules_->low_cut_filter.reset( - new LowCutFilter(num_proc_channels(), proc_sample_rate_hz())); +void AudioProcessingImpl::InitializeHighPassFilter() { + if (submodule_states_.HighPassFilteringRequired()) { + private_submodules_->high_pass_filter.reset( + new HighPassFilter(num_proc_channels())); } else { - private_submodules_->low_cut_filter.reset(); + private_submodules_->high_pass_filter.reset(); } } @@ -1850,7 +1849,7 @@ void AudioProcessingImpl::InitializeEchoController() { echo_control_factory_->Create(proc_sample_rate_hz()); } else { private_submodules_->echo_controller = absl::make_unique( - EchoCanceller3Config(), proc_sample_rate_hz(), true); + EchoCanceller3Config(), proc_sample_rate_hz()); } capture_nonlocked_.echo_controller_enabled = true; diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h index 1539cd582a..6bda06a002 100644 --- a/modules/audio_processing/audio_processing_impl.h +++ b/modules/audio_processing/audio_processing_impl.h @@ -193,7 +193,7 @@ class AudioProcessingImpl : public AudioProcessing { bool RenderMultiBandSubModulesActive() const; bool RenderFullBandProcessingActive() const; bool RenderMultiBandProcessingActive() const; - bool LowCutFilteringRequired() const; + bool HighPassFilteringRequired() const; private: const bool capture_post_processor_enabled_ = false; @@ -238,7 +238,7 @@ class AudioProcessingImpl : public AudioProcessing { RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_); void InitializeResidualEchoDetector() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_); - void InitializeLowCutFilter() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_); + void InitializeHighPassFilter() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_); void InitializeEchoController() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_); void InitializeGainController2() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_); diff --git a/modules/audio_processing/audio_processing_impl_unittest.cc b/modules/audio_processing/audio_processing_impl_unittest.cc index f6953ab63f..72bd673531 100644 --- a/modules/audio_processing/audio_processing_impl_unittest.cc +++ b/modules/audio_processing/audio_processing_impl_unittest.cc @@ -239,13 +239,13 @@ TEST(AudioProcessingImplTest, MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext(); - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), /*echo_path_change=*/false)) .Times(1); apm->ProcessStream(&frame); - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), /*echo_path_change=*/true)) .Times(1); @@ -282,7 +282,7 @@ TEST(AudioProcessingImplTest, MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext(); const int initial_analog_gain = apm->gain_control()->stream_analog_level(); - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), false)).Times(1); apm->ProcessStream(&frame); @@ -291,7 +291,7 @@ TEST(AudioProcessingImplTest, apm->gain_control()->set_stream_analog_level(initial_analog_gain + 1); } - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), true)).Times(1); apm->ProcessStream(&frame); } @@ -318,13 +318,13 @@ TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) { MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext(); - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), /*echo_path_change=*/false)) .Times(1); apm->ProcessStream(&frame); - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), /*echo_path_change=*/false)) .Times(1); @@ -332,7 +332,7 @@ TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) { AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50)); apm->ProcessStream(&frame); - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), /*echo_path_change=*/false)) .Times(1); @@ -340,7 +340,7 @@ TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) { AudioProcessing::RuntimeSetting::CreatePlayoutVolumeChange(50)); apm->ProcessStream(&frame); - EXPECT_CALL(*echo_control_mock, AnalyzeCapture(NotNull())).Times(1); + EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1); EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), /*echo_path_change=*/true)) .Times(1); diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc index 461236ee3a..23657b8e45 100644 --- a/modules/audio_processing/audio_processing_unittest.cc +++ b/modules/audio_processing/audio_processing_unittest.cc @@ -2204,15 +2204,15 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( CommonFormats, AudioProcessingTest, - ::testing::Values(std::make_tuple(48000, 48000, 48000, 48000, 20, 0), - std::make_tuple(48000, 48000, 32000, 48000, 20, 30), - std::make_tuple(48000, 48000, 16000, 48000, 20, 20), + ::testing::Values(std::make_tuple(48000, 48000, 48000, 48000, 19, 0), + std::make_tuple(48000, 48000, 32000, 48000, 19, 30), + std::make_tuple(48000, 48000, 16000, 48000, 19, 20), std::make_tuple(48000, 44100, 48000, 44100, 15, 20), std::make_tuple(48000, 44100, 32000, 44100, 15, 15), std::make_tuple(48000, 44100, 16000, 44100, 15, 15), - std::make_tuple(48000, 32000, 48000, 32000, 20, 35), - std::make_tuple(48000, 32000, 32000, 32000, 20, 0), - std::make_tuple(48000, 32000, 16000, 32000, 20, 20), + std::make_tuple(48000, 32000, 48000, 32000, 19, 35), + std::make_tuple(48000, 32000, 32000, 32000, 19, 0), + std::make_tuple(48000, 32000, 16000, 32000, 19, 20), std::make_tuple(48000, 16000, 48000, 16000, 20, 20), std::make_tuple(48000, 16000, 32000, 16000, 20, 20), std::make_tuple(48000, 16000, 16000, 16000, 20, 0), @@ -2223,12 +2223,12 @@ INSTANTIATE_TEST_SUITE_P( std::make_tuple(44100, 44100, 48000, 44100, 15, 20), std::make_tuple(44100, 44100, 32000, 44100, 15, 15), std::make_tuple(44100, 44100, 16000, 44100, 15, 15), - std::make_tuple(44100, 32000, 48000, 32000, 20, 35), - std::make_tuple(44100, 32000, 32000, 32000, 20, 0), - std::make_tuple(44100, 32000, 16000, 32000, 20, 20), - std::make_tuple(44100, 16000, 48000, 16000, 20, 20), - std::make_tuple(44100, 16000, 32000, 16000, 20, 20), - std::make_tuple(44100, 16000, 16000, 16000, 20, 0), + std::make_tuple(44100, 32000, 48000, 32000, 18, 35), + std::make_tuple(44100, 32000, 32000, 32000, 18, 0), + std::make_tuple(44100, 32000, 16000, 32000, 18, 20), + std::make_tuple(44100, 16000, 48000, 16000, 19, 20), + std::make_tuple(44100, 16000, 32000, 16000, 19, 20), + std::make_tuple(44100, 16000, 16000, 16000, 19, 0), std::make_tuple(32000, 48000, 48000, 48000, 35, 0), std::make_tuple(32000, 48000, 32000, 48000, 65, 30), diff --git a/modules/audio_processing/high_pass_filter.cc b/modules/audio_processing/high_pass_filter.cc new file mode 100644 index 0000000000..306bcbd776 --- /dev/null +++ b/modules/audio_processing/high_pass_filter.cc @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012 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/high_pass_filter.h" + +#include "api/array_view.h" +#include "modules/audio_processing/audio_buffer.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +namespace { +// [B,A] = butter(2,100/8000,'high') +constexpr CascadedBiQuadFilter::BiQuadCoefficients kHighPassFilterCoefficients = + {{0.97261f, -1.94523f, 0.97261f}, {-1.94448f, 0.94598f}}; + +constexpr size_t kNumberOfHighPassBiQuads = 1; + +} // namespace + +HighPassFilter::HighPassFilter(size_t num_channels) { + filters_.resize(num_channels); + for (size_t k = 0; k < filters_.size(); ++k) { + filters_[k].reset(new CascadedBiQuadFilter(kHighPassFilterCoefficients, + kNumberOfHighPassBiQuads)); + } +} + +HighPassFilter::~HighPassFilter() = default; + +void HighPassFilter::Process(AudioBuffer* audio) { + RTC_DCHECK(audio); + RTC_DCHECK_EQ(filters_.size(), audio->num_channels()); + for (size_t k = 0; k < audio->num_channels(); ++k) { + rtc::ArrayView channel_data = rtc::ArrayView( + audio->split_bands(k)[0], audio->num_frames_per_band()); + filters_[k]->Process(channel_data); + } +} + +void HighPassFilter::Process(rtc::ArrayView audio) { + RTC_DCHECK_EQ(filters_.size(), 1); + filters_[0]->Process(audio); +} + +void HighPassFilter::Reset() { + for (size_t k = 0; k < filters_.size(); ++k) { + filters_[k]->Reset(); + } +} + +void HighPassFilter::Reset(size_t num_channels) { + const size_t old_num_channels = filters_.size(); + filters_.resize(num_channels); + if (filters_.size() < old_num_channels) { + Reset(); + } else { + for (size_t k = 0; k < old_num_channels; ++k) { + filters_[k]->Reset(); + } + for (size_t k = old_num_channels; k < filters_.size(); ++k) { + filters_[k].reset(new CascadedBiQuadFilter(kHighPassFilterCoefficients, + kNumberOfHighPassBiQuads)); + } + } +} + +} // namespace webrtc diff --git a/modules/audio_processing/high_pass_filter.h b/modules/audio_processing/high_pass_filter.h new file mode 100644 index 0000000000..b0682061bf --- /dev/null +++ b/modules/audio_processing/high_pass_filter.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012 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_HIGH_PASS_FILTER_H_ +#define MODULES_AUDIO_PROCESSING_HIGH_PASS_FILTER_H_ + +#include +#include + +#include "api/array_view.h" +#include "modules/audio_processing/utility/cascaded_biquad_filter.h" + +namespace webrtc { + +class AudioBuffer; + +// Filters that high +class HighPassFilter { + public: + explicit HighPassFilter(size_t num_channels); + ~HighPassFilter(); + HighPassFilter(const HighPassFilter&) = delete; + HighPassFilter& operator=(const HighPassFilter&) = delete; + + void Process(AudioBuffer* audio); + // Only to be used when the number of channels are 1. + // TODO(peah): Add support for more channels. + void Process(rtc::ArrayView audio); + void Reset(); + void Reset(size_t num_channels); + + private: + std::vector> filters_; +}; +} // namespace webrtc + +#endif // MODULES_AUDIO_PROCESSING_HIGH_PASS_FILTER_H_ diff --git a/modules/audio_processing/high_pass_filter_unittest.cc b/modules/audio_processing/high_pass_filter_unittest.cc new file mode 100644 index 0000000000..4025454d18 --- /dev/null +++ b/modules/audio_processing/high_pass_filter_unittest.cc @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2015 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/high_pass_filter.h" + +#include + +#include "api/array_view.h" +#include "modules/audio_processing/audio_buffer.h" +#include "modules/audio_processing/test/audio_buffer_tools.h" +#include "modules/audio_processing/test/bitexactness_tools.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +// Process one frame of data and produce the output. +std::vector ProcessOneFrame(const std::vector& frame_input, + const StreamConfig& stream_config, + HighPassFilter* high_pass_filter) { + AudioBuffer audio_buffer( + stream_config.sample_rate_hz(), stream_config.num_channels(), + stream_config.sample_rate_hz(), stream_config.num_channels(), + stream_config.sample_rate_hz(), stream_config.num_channels()); + + test::CopyVectorToAudioBuffer(stream_config, frame_input, &audio_buffer); + high_pass_filter->Process(&audio_buffer); + std::vector frame_output; + test::ExtractVectorFromAudioBuffer(stream_config, &audio_buffer, + &frame_output); + return frame_output; +} + +// Processes a specified amount of frames, verifies the results and reports +// any errors. +void RunBitexactnessTest(int num_channels, + const std::vector& input, + const std::vector& reference) { + const StreamConfig stream_config(16000, num_channels, false); + HighPassFilter high_pass_filter(num_channels); + + std::vector output; + const size_t num_frames_to_process = + input.size() / + (stream_config.num_frames() * stream_config.num_channels()); + for (size_t frame_no = 0; frame_no < num_frames_to_process; ++frame_no) { + std::vector frame_input( + input.begin() + stream_config.num_frames() * + stream_config.num_channels() * frame_no, + input.begin() + stream_config.num_frames() * + stream_config.num_channels() * (frame_no + 1)); + + output = ProcessOneFrame(frame_input, stream_config, &high_pass_filter); + } + + // Form vector to compare the reference to. Only the last frame processed + // is compared in order not having to specify all preceeding frames as + // inputs. As the algorithm being tested has a memory, testing only + // the last frame implicitly also tests the preceeding frames. + const size_t reference_frame_length = + reference.size() / stream_config.num_channels(); + std::vector output_to_verify; + for (size_t channel_no = 0; channel_no < stream_config.num_channels(); + ++channel_no) { + output_to_verify.insert( + output_to_verify.end(), + output.begin() + channel_no * stream_config.num_frames(), + output.begin() + channel_no * stream_config.num_frames() + + reference_frame_length); + } + + const float kElementErrorBound = 1.0f / 32768.0f; + EXPECT_TRUE(test::VerifyDeinterleavedArray( + reference_frame_length, num_channels, reference, output_to_verify, + kElementErrorBound)); +} + +// Method for forming a vector out of an array. +// TODO(peah): Remove once braced initialization is allowed. +std::vector CreateVector(const rtc::ArrayView& array_view) { + std::vector v; + for (auto value : array_view) { + v.push_back(value); + } + return v; +} +} // namespace + +TEST(HighPassFilterAccuracyTest, Reset) { + const StreamConfig stream_config_stereo(16000, 2, false); + const StreamConfig stream_config_mono(16000, 1, false); + std::vector x_mono(160, 1.f); + std::vector x_stereo(320, 1.f); + HighPassFilter lc(1); + std::vector y = ProcessOneFrame(x_mono, stream_config_mono, &lc); + lc.Reset(2); + y = ProcessOneFrame(x_stereo, stream_config_stereo, &lc); + lc.Reset(1); + y = ProcessOneFrame(x_mono, stream_config_mono, &lc); + lc.Reset(); + y = ProcessOneFrame(x_mono, stream_config_mono, &lc); +} + +TEST(HighPassFilterAccuracyTest, MonoInitial) { + const float kReferenceInput[] = { + 0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f, + -0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f, + 0.202718f, -0.017621f, 0.199738f, -0.057279f, -0.034693f, 0.416303f, + 0.393761f, 0.396041f, 0.187653f, -0.337438f, 0.200436f, 0.455577f, + 0.136624f, 0.289150f, 0.203131f, -0.084798f, 0.082124f, -0.220010f, + 0.248266f, -0.320554f, -0.298701f, -0.226218f, -0.822794f, 0.401962f, + 0.090876f, -0.210968f, 0.382936f, -0.478291f, -0.028572f, -0.067474f, + 0.089204f, 0.087430f, -0.241695f, -0.008398f, -0.046076f, 0.175416f, + 0.305518f, 0.309992f, -0.241352f, 0.021618f, -0.339291f, -0.311173f, + -0.001914f, 0.428301f, -0.215087f, 0.103784f, -0.063041f, 0.312250f, + -0.304344f, 0.009098f, 0.154406f, 0.307571f, 0.431537f, 0.024014f, + -0.416832f, -0.207440f, -0.296664f, 0.656846f, -0.172033f, 0.209054f, + -0.053772f, 0.248326f, -0.213741f, -0.391871f, -0.397490f, 0.136428f, + -0.049568f, -0.054788f, 0.396633f, 0.081485f, 0.055279f, 0.443690f, + -0.224812f, 0.194675f, 0.233369f, -0.068107f, 0.060270f, -0.325801f, + -0.320801f, 0.029308f, 0.201837f, 0.722528f, -0.186366f, 0.052351f, + -0.023053f, -0.540192f, -0.122671f, -0.501532f, 0.234847f, -0.248165f, + 0.027971f, -0.152171f, 0.084820f, -0.167764f, 0.136923f, 0.206619f, + 0.478395f, -0.054249f, -0.597574f, -0.234627f, 0.378548f, -0.299619f, + 0.268543f, 0.034666f, 0.401492f, -0.547983f, -0.055248f, -0.337538f, + 0.812657f, 0.230611f, 0.385360f, -0.295713f, -0.130957f, -0.076143f, + 0.306960f, -0.077653f, 0.196049f, -0.573390f, -0.098885f, -0.230155f, + -0.440716f, 0.141956f, 0.078802f, 0.009356f, -0.372703f, 0.315083f, + 0.097859f, -0.083575f, 0.006397f, -0.073216f, -0.489105f, -0.079827f, + -0.232329f, -0.273644f, -0.323162f, -0.149105f, -0.559646f, 0.269458f, + 0.145333f, -0.005597f, -0.009717f, -0.223051f, 0.284676f, -0.037228f, + -0.199679f, 0.377651f, -0.062813f, -0.164607f}; + const float kReference[] = {0.146139f, 0.490336f, -0.649520f, 0.233881f, + 0.073214f, -0.373256f, -0.115394f, 0.102109f, + 0.976217f, 0.702270f, -0.457697f, 0.757116f}; + + RunBitexactnessTest( + 1, CreateVector(rtc::ArrayView(kReferenceInput)), + CreateVector(rtc::ArrayView(kReference))); +} + +TEST(HighPassFilterAccuracyTest, MonoConverged) { + const float kReferenceInput[] = { + 0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f, + -0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f, + 0.202718f, -0.017621f, 0.199738f, -0.057279f, -0.034693f, 0.416303f, + 0.393761f, 0.396041f, 0.187653f, -0.337438f, 0.200436f, 0.455577f, + 0.136624f, 0.289150f, 0.203131f, -0.084798f, 0.082124f, -0.220010f, + 0.248266f, -0.320554f, -0.298701f, -0.226218f, -0.822794f, 0.401962f, + 0.090876f, -0.210968f, 0.382936f, -0.478291f, -0.028572f, -0.067474f, + 0.089204f, 0.087430f, -0.241695f, -0.008398f, -0.046076f, 0.175416f, + 0.305518f, 0.309992f, -0.241352f, 0.021618f, -0.339291f, -0.311173f, + -0.001914f, 0.428301f, -0.215087f, 0.103784f, -0.063041f, 0.312250f, + -0.304344f, 0.009098f, 0.154406f, 0.307571f, 0.431537f, 0.024014f, + -0.416832f, -0.207440f, -0.296664f, 0.656846f, -0.172033f, 0.209054f, + -0.053772f, 0.248326f, -0.213741f, -0.391871f, -0.397490f, 0.136428f, + -0.049568f, -0.054788f, 0.396633f, 0.081485f, 0.055279f, 0.443690f, + -0.224812f, 0.194675f, 0.233369f, -0.068107f, 0.060270f, -0.325801f, + -0.320801f, 0.029308f, 0.201837f, 0.722528f, -0.186366f, 0.052351f, + -0.023053f, -0.540192f, -0.122671f, -0.501532f, 0.234847f, -0.248165f, + 0.027971f, -0.152171f, 0.084820f, -0.167764f, 0.136923f, 0.206619f, + 0.478395f, -0.054249f, -0.597574f, -0.234627f, 0.378548f, -0.299619f, + 0.268543f, 0.034666f, 0.401492f, -0.547983f, -0.055248f, -0.337538f, + 0.812657f, 0.230611f, 0.385360f, -0.295713f, -0.130957f, -0.076143f, + 0.306960f, -0.077653f, 0.196049f, -0.573390f, -0.098885f, -0.230155f, + -0.440716f, 0.141956f, 0.078802f, 0.009356f, -0.372703f, 0.315083f, + 0.097859f, -0.083575f, 0.006397f, -0.073216f, -0.489105f, -0.079827f, + -0.232329f, -0.273644f, -0.323162f, -0.149105f, -0.559646f, 0.269458f, + 0.145333f, -0.005597f, -0.009717f, -0.223051f, 0.284676f, -0.037228f, + -0.199679f, 0.377651f, -0.062813f, -0.164607f, -0.082091f, -0.236957f, + -0.313025f, 0.705903f, 0.462637f, 0.085942f, -0.351308f, -0.241859f, + -0.049333f, 0.221165f, -0.372235f, -0.651092f, -0.404957f, 0.093201f, + 0.109366f, 0.126224f, -0.036409f, 0.051333f, -0.133063f, 0.240896f, + -0.380532f, 0.127160f, -0.237176f, -0.093586f, 0.154478f, 0.290379f, + -0.312329f, 0.352297f, 0.184480f, -0.018965f, -0.054555f, -0.060811f, + -0.084705f, 0.006440f, 0.014333f, 0.230847f, 0.426721f, 0.130481f, + -0.058605f, 0.174712f, 0.051204f, -0.287773f, 0.265265f, 0.085810f, + 0.037775f, 0.143988f, 0.073051f, -0.263103f, -0.045366f, -0.040816f, + -0.148673f, 0.470072f, -0.244727f, -0.135204f, -0.198973f, -0.328139f, + -0.053722f, -0.076590f, 0.427586f, -0.069591f, -0.297399f, 0.448094f, + 0.345037f, -0.064170f, -0.420903f, -0.124253f, -0.043578f, 0.077149f, + -0.072983f, 0.123916f, 0.109517f, -0.349508f, -0.264912f, -0.207106f, + -0.141912f, -0.089586f, 0.003485f, -0.846518f, -0.127715f, 0.347208f, + -0.298095f, 0.260935f, 0.097899f, -0.008106f, 0.050987f, -0.437362f, + -0.023625f, 0.448230f, 0.027484f, 0.011562f, -0.205167f, -0.008611f, + 0.064930f, 0.119156f, -0.104183f, -0.066078f, 0.565530f, -0.631108f, + 0.623029f, 0.094334f, 0.279472f, -0.465059f, -0.164888f, -0.077706f, + 0.118130f, -0.466746f, 0.131800f, -0.338936f, 0.018497f, 0.182304f, + 0.091398f, 0.302547f, 0.281153f, -0.181899f, 0.071836f, -0.263911f, + -0.369380f, 0.258447f, 0.000014f, -0.015347f, 0.254619f, 0.166159f, + 0.097865f, 0.349389f, 0.259834f, 0.067003f, -0.192925f, -0.182080f, + 0.333139f, -0.450434f, -0.006836f, -0.544615f, 0.285183f, 0.240811f, + 0.000325f, -0.019796f, -0.694804f, 0.162411f, -0.612686f, -0.648134f, + 0.022338f, -0.265058f, 0.114993f, 0.189185f, 0.239697f, -0.193148f, + 0.125581f, 0.028122f, 0.230849f, 0.149832f, 0.250919f, -0.036871f, + -0.041136f, 0.281627f, -0.593466f, -0.141009f, -0.355074f, -0.106915f, + 0.181276f, 0.230753f, -0.283631f, -0.131643f, 0.038292f, -0.081563f, + 0.084345f, 0.111763f, -0.259882f, -0.049416f, -0.595824f, 0.320077f, + -0.175802f, -0.336422f, -0.070966f, -0.399242f, -0.005829f, -0.156680f, + 0.608591f, 0.318150f, -0.697767f, 0.123331f, -0.390716f, -0.071276f, + 0.045943f, 0.208958f, -0.076304f, 0.440505f, -0.134400f, 0.091525f, + 0.185763f, 0.023806f, 0.246186f, 0.090323f, -0.219133f, -0.504520f, + 0.519393f, -0.168939f, 0.028884f, 0.157380f, 0.031745f, -0.252830f, + -0.130705f, -0.034901f, 0.413302f, -0.240559f, 0.219279f, 0.086246f, + -0.065353f, -0.295376f, -0.079405f, -0.024226f, -0.410629f, 0.053706f, + -0.229794f, -0.026336f, 0.093956f, -0.252810f, -0.080555f, 0.097827f, + -0.513040f, 0.289508f, 0.677527f, 0.268109f, -0.088244f, 0.119781f, + -0.289511f, 0.524778f, 0.262884f, 0.220028f, -0.244767f, 0.089411f, + -0.156018f, -0.087030f, -0.159292f, -0.286646f, -0.253953f, -0.058657f, + -0.474756f, 0.169797f, -0.032919f, 0.195384f, 0.075355f, 0.138131f, + -0.414465f, -0.285118f, -0.124915f, 0.030645f, 0.315431f, -0.081032f, + 0.352546f, 0.132860f, 0.328112f, 0.035476f, -0.183550f, -0.413984f, + 0.043452f, 0.228748f, -0.081765f, -0.151125f, -0.086251f, -0.306448f, + -0.137774f, -0.050508f, 0.012811f, -0.017824f, 0.170841f, 0.030549f, + 0.506935f, 0.087197f, 0.504274f, -0.202080f, 0.147146f, -0.072728f, + 0.167713f, 0.165977f, -0.610894f, -0.370849f, -0.402698f, 0.112297f, + 0.410855f, -0.091330f, 0.227008f, 0.152454f, -0.293884f, 0.111074f, + -0.210121f, 0.423728f, -0.009101f, 0.457188f, -0.118785f, 0.164720f, + -0.017547f, -0.565046f, -0.274461f, 0.171169f, -0.015338f, -0.312635f, + -0.175044f, 0.069729f, -0.277504f, 0.272454f, -0.179049f, 0.505495f, + -0.301774f, 0.055664f, -0.425058f, -0.202222f, -0.165787f, 0.112155f, + 0.263284f, 0.083972f, -0.104256f, 0.227892f, 0.223253f, 0.033592f, + 0.159638f, 0.115358f, -0.275811f, 0.212265f, -0.183658f, -0.168768f}; + + const float kReference[] = {-0.248836f, -0.086982f, 0.083715f, -0.036787f, + 0.127212f, 0.147464f, -0.221733f, -0.004484f, + -0.535107f, 0.385999f, -0.116346f, -0.265302f}; + + RunBitexactnessTest( + 1, CreateVector(rtc::ArrayView(kReferenceInput)), + CreateVector(rtc::ArrayView(kReference))); +} + +} // namespace webrtc diff --git a/modules/audio_processing/include/mock_audio_processing.h b/modules/audio_processing/include/mock_audio_processing.h index 141a8acf98..1c08726260 100644 --- a/modules/audio_processing/include/mock_audio_processing.h +++ b/modules/audio_processing/include/mock_audio_processing.h @@ -13,6 +13,7 @@ #include +#include "modules/audio_processing/audio_buffer.h" #include "modules/audio_processing/include/aec_dump.h" #include "modules/audio_processing/include/audio_processing.h" #include "modules/audio_processing/include/audio_processing_statistics.h" diff --git a/modules/audio_processing/low_cut_filter.cc b/modules/audio_processing/low_cut_filter.cc deleted file mode 100644 index 307a7e8549..0000000000 --- a/modules/audio_processing/low_cut_filter.cc +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2012 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/low_cut_filter.h" - -#include - -#include - -#include "common_audio/signal_processing/include/signal_processing_library.h" -#include "modules/audio_processing/audio_buffer.h" -#include "modules/audio_processing/include/audio_processing.h" -#include "rtc_base/checks.h" - -namespace webrtc { -namespace { -const int16_t kFilterCoefficients8kHz[5] = {3798, -7596, 3798, 7807, -3733}; -const int16_t kFilterCoefficients[5] = {4012, -8024, 4012, 8002, -3913}; -} // namespace - -class LowCutFilter::BiquadFilter { - public: - explicit BiquadFilter(int sample_rate_hz) - : ba_(sample_rate_hz == AudioProcessing::kSampleRate8kHz - ? kFilterCoefficients8kHz - : kFilterCoefficients) { - std::memset(x_, 0, sizeof(x_)); - std::memset(y_, 0, sizeof(y_)); - } - - void Process(int16_t* data, size_t length) { - const int16_t* const ba = ba_; - int16_t* x = x_; - int16_t* y = y_; - int32_t tmp_int32 = 0; - - for (size_t i = 0; i < length; i++) { - // y[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2] - // + -a[1] * y[i-1] + -a[2] * y[i-2]; - - tmp_int32 = y[1] * ba[3]; // -a[1] * y[i-1] (low part) - tmp_int32 += y[3] * ba[4]; // -a[2] * y[i-2] (low part) - tmp_int32 = (tmp_int32 >> 15); - tmp_int32 += y[0] * ba[3]; // -a[1] * y[i-1] (high part) - tmp_int32 += y[2] * ba[4]; // -a[2] * y[i-2] (high part) - tmp_int32 *= 2; - - tmp_int32 += data[i] * ba[0]; // b[0] * x[0] - tmp_int32 += x[0] * ba[1]; // b[1] * x[i-1] - tmp_int32 += x[1] * ba[2]; // b[2] * x[i-2] - - // Update state (input part). - x[1] = x[0]; - x[0] = data[i]; - - // Update state (filtered part). - y[2] = y[0]; - y[3] = y[1]; - y[0] = static_cast(tmp_int32 >> 13); - - y[1] = static_cast((tmp_int32 & 0x00001FFF) * 4); - - // Rounding in Q12, i.e. add 2^11. - tmp_int32 += 2048; - - // Saturate (to 2^27) so that the HP filtered signal does not overflow. - tmp_int32 = WEBRTC_SPL_SAT(static_cast(134217727), tmp_int32, - static_cast(-134217728)); - - // Convert back to Q0 and use rounding. - data[i] = static_cast(tmp_int32 >> 12); - } - } - - private: - const int16_t* const ba_; - int16_t x_[2]; - int16_t y_[4]; -}; - -LowCutFilter::LowCutFilter(size_t channels, int sample_rate_hz) { - filters_.resize(channels); - for (size_t i = 0; i < channels; i++) { - filters_[i].reset(new BiquadFilter(sample_rate_hz)); - } -} - -LowCutFilter::~LowCutFilter() {} - -void LowCutFilter::Process(AudioBuffer* audio) { - RTC_DCHECK(audio); - RTC_DCHECK_GE(AudioBuffer::kMaxSplitFrameLength, - audio->num_frames_per_band()); - RTC_DCHECK_EQ(filters_.size(), audio->num_channels()); - for (size_t i = 0; i < filters_.size(); i++) { - std::array samples_fixed; - FloatS16ToS16(audio->split_bands(i)[kBand0To8kHz], - audio->num_frames_per_band(), samples_fixed.data()); - - filters_[i]->Process(samples_fixed.data(), audio->num_frames_per_band()); - - S16ToFloatS16(samples_fixed.data(), audio->num_frames_per_band(), - audio->split_bands(i)[kBand0To8kHz]); - } -} - -} // namespace webrtc diff --git a/modules/audio_processing/low_cut_filter.h b/modules/audio_processing/low_cut_filter.h deleted file mode 100644 index 86fbddd04b..0000000000 --- a/modules/audio_processing/low_cut_filter.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2012 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_LOW_CUT_FILTER_H_ -#define MODULES_AUDIO_PROCESSING_LOW_CUT_FILTER_H_ - -#include -#include - -#include "rtc_base/constructor_magic.h" - -namespace webrtc { - -class AudioBuffer; - -class LowCutFilter { - public: - LowCutFilter(size_t channels, int sample_rate_hz); - ~LowCutFilter(); - void Process(AudioBuffer* audio); - - private: - class BiquadFilter; - std::vector> filters_; - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(LowCutFilter); -}; -} // namespace webrtc - -#endif // MODULES_AUDIO_PROCESSING_LOW_CUT_FILTER_H_ diff --git a/modules/audio_processing/low_cut_filter_unittest.cc b/modules/audio_processing/low_cut_filter_unittest.cc deleted file mode 100644 index 02c86e4357..0000000000 --- a/modules/audio_processing/low_cut_filter_unittest.cc +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (c) 2015 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/low_cut_filter.h" - -#include - -#include "api/array_view.h" -#include "modules/audio_processing/audio_buffer.h" -#include "modules/audio_processing/test/audio_buffer_tools.h" -#include "modules/audio_processing/test/bitexactness_tools.h" -#include "test/gtest.h" - -namespace webrtc { -namespace { - -// Process one frame of data and produce the output. -std::vector ProcessOneFrame(const std::vector& frame_input, - const StreamConfig& stream_config, - LowCutFilter* low_cut_filter) { - AudioBuffer audio_buffer( - stream_config.sample_rate_hz(), stream_config.num_channels(), - stream_config.sample_rate_hz(), stream_config.num_channels(), - stream_config.sample_rate_hz(), stream_config.num_channels()); - - test::CopyVectorToAudioBuffer(stream_config, frame_input, &audio_buffer); - low_cut_filter->Process(&audio_buffer); - std::vector frame_output; - test::ExtractVectorFromAudioBuffer(stream_config, &audio_buffer, - &frame_output); - return frame_output; -} - -// Processes a specified amount of frames, verifies the results and reports -// any errors. -void RunBitexactnessTest(int sample_rate, - int num_channels, - const std::vector& input, - const std::vector& reference) { - const StreamConfig stream_config(sample_rate, num_channels, false); - LowCutFilter low_cut_filter(num_channels, sample_rate); - - std::vector output; - const size_t num_frames_to_process = - input.size() / - (stream_config.num_frames() * stream_config.num_channels()); - for (size_t frame_no = 0; frame_no < num_frames_to_process; ++frame_no) { - std::vector frame_input( - input.begin() + stream_config.num_frames() * - stream_config.num_channels() * frame_no, - input.begin() + stream_config.num_frames() * - stream_config.num_channels() * (frame_no + 1)); - - output = ProcessOneFrame(frame_input, stream_config, &low_cut_filter); - } - - // Form vector to compare the reference to. Only the last frame processed - // is compared in order not having to specify all preceeding frames as - // inputs. As the algorithm being tested has a memory, testing only - // the last frame implicitly also tests the preceeding frames. - const size_t reference_frame_length = - reference.size() / stream_config.num_channels(); - std::vector output_to_verify; - for (size_t channel_no = 0; channel_no < stream_config.num_channels(); - ++channel_no) { - output_to_verify.insert( - output_to_verify.end(), - output.begin() + channel_no * stream_config.num_frames(), - output.begin() + channel_no * stream_config.num_frames() + - reference_frame_length); - } - - const float kElementErrorBound = 1.0f / 32768.0f; - EXPECT_TRUE(test::VerifyDeinterleavedArray( - reference_frame_length, num_channels, reference, output_to_verify, - kElementErrorBound)); -} - -// Method for forming a vector out of an array. -// TODO(peah): Remove once braced initialization is allowed. -std::vector CreateVector(const rtc::ArrayView& array_view) { - std::vector v; - for (auto value : array_view) { - v.push_back(value); - } - return v; -} -} // namespace - -TEST(LowCutFilterBitExactnessTest, Mono8kHzInitial) { - const float kReferenceInput[] = { - 0.153442f, -0.436920f, -0.057602f, -0.141767f, 0.108608f, 0.116834f, - 0.114979f, -0.103151f, -0.169925f, -0.167180f, 0.242024f, -0.525426f, - -0.058781f, 0.076667f, -0.185095f, 0.135319f, -0.020223f, -0.266058f, - 0.045755f, -0.076044f, -0.116221f, -0.201698f, 0.017423f, -0.523475f, - -0.112949f, -0.154125f, -0.258572f, 0.185075f, -0.208205f, 0.153298f, - 0.276703f, -0.044481f, 0.078771f, 0.181337f, -0.022962f, 0.153365f, - -0.358004f, 0.314864f, -0.280593f, -0.518572f, 0.392579f, -0.017786f, - 0.127293f, -0.103003f, -0.289389f, -0.871355f, 0.177583f, -0.081290f, - -0.055957f, 0.115011f, -0.402460f, -0.206836f, 0.325328f, 0.169526f, - -0.363311f, -0.624742f, -0.161979f, 0.060679f, 0.267214f, 0.026576f, - -0.318235f, 0.086812f, -0.332419f, -0.272485f, -0.185369f, -0.348598f, - -0.076833f, -0.255184f, -0.081007f, -0.131121f, -0.116196f, -0.142780f, - 0.349705f, 0.173054f, 0.016750f, -0.415957f, -0.461001f, -0.557111f, - 0.738711f, 0.275720f}; - - const float kReference[] = {0.142273f, -0.418518f, -0.028229f, -0.102112f, - 0.141266f, 0.137787f, 0.124573f, -0.088715f, - -0.142273f, -0.125885f, 0.266663f, -0.468109f}; - - RunBitexactnessTest( - 8000, 1, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} - -TEST(LowCutFilterBitExactnessTest, Mono8kHzConverged) { - const float kReferenceInput[] = { - 0.153442f, -0.436920f, -0.057602f, -0.141767f, 0.108608f, 0.116834f, - 0.114979f, -0.103151f, -0.169925f, -0.167180f, 0.242024f, -0.525426f, - -0.058781f, 0.076667f, -0.185095f, 0.135319f, -0.020223f, -0.266058f, - 0.045755f, -0.076044f, -0.116221f, -0.201698f, 0.017423f, -0.523475f, - -0.112949f, -0.154125f, -0.258572f, 0.185075f, -0.208205f, 0.153298f, - 0.276703f, -0.044481f, 0.078771f, 0.181337f, -0.022962f, 0.153365f, - -0.358004f, 0.314864f, -0.280593f, -0.518572f, 0.392579f, -0.017786f, - 0.127293f, -0.103003f, -0.289389f, -0.871355f, 0.177583f, -0.081290f, - -0.055957f, 0.115011f, -0.402460f, -0.206836f, 0.325328f, 0.169526f, - -0.363311f, -0.624742f, -0.161979f, 0.060679f, 0.267214f, 0.026576f, - -0.318235f, 0.086812f, -0.332419f, -0.272485f, -0.185369f, -0.348598f, - -0.076833f, -0.255184f, -0.081007f, -0.131121f, -0.116196f, -0.142780f, - 0.349705f, 0.173054f, 0.016750f, -0.415957f, -0.461001f, -0.557111f, - 0.738711f, 0.275720f, 0.072868f, -0.276249f, -0.325055f, 0.155285f, - 0.443784f, -0.480153f, -0.127428f, -0.023901f, -0.564837f, 0.238538f, - -0.117578f, 0.542205f, -0.110840f, 0.116025f, -0.323939f, -0.177182f, - -0.331395f, 0.111316f, 0.369140f, -0.168329f, 0.123736f, -0.143013f, - 0.028953f, 0.339200f, 0.034107f, -0.294000f, -0.243034f, -0.048168f, - -0.054348f, -0.245504f, 0.051228f, 0.359128f, -0.071220f, -0.058006f, - -0.624248f, -0.219615f, -0.395067f, -0.109518f, 0.149032f, 0.431928f, - 0.509968f, -0.033143f, -0.090793f, 0.231809f, 0.138986f, 0.216989f, - 0.220683f, -0.419745f, 0.153222f, -0.025956f, -0.215572f, -0.196671f, - 0.363361f, -0.229604f, -0.350704f, 0.060875f, 0.570160f, 0.007246f, - 0.087419f, -0.266043f, 0.474729f, 0.035441f, 0.150312f, -0.269962f, - 0.242166f, 0.110343f, -0.327788f, 0.011268f, -0.127769f, 0.030978f, - -0.071045f, -0.053847f, -0.292886f, -0.091670f, 0.217351f, 0.494707f, - -0.329069f, 0.674122f, 0.432724f, 0.047781f, -0.085408f, -0.198105f, - 0.236135f, -0.196957f, -0.130968f, 0.250552f, 0.123613f, 0.254275f, - 0.143118f, -0.113676f, -0.145703f, 0.225812f, -0.190318f, 0.336481f, - 0.224206f, 0.081584f, 0.000915f, 0.103672f, 1.000000f, -0.031882f, - -0.441377f, 0.543033f, 0.172924f, -0.183717f, 0.742153f, 0.156224f, - 0.083422f, -0.220560f, -0.301964f, -0.501439f, -0.119920f, -0.298610f, - 0.183673f, -0.090064f, 0.501603f, 0.428330f, 0.046506f, -0.080178f, - 0.326700f, -0.325096f, 0.191029f, -0.189729f, -0.113513f, -0.190492f, - 0.163221f, -0.220631f, -0.301576f, 0.156799f, -0.120065f, 0.102529f, - -0.099779f, 0.076429f, -0.727157f, 0.132097f, 0.525583f, 0.294694f, - 0.258287f, -0.067977f, 0.051323f, 0.069258f, 0.027332f, -0.235482f, - -0.099882f, -0.049558f, -0.136291f, 0.237288f, 0.719757f, -0.375235f, - 0.036391f, -0.408991f, 0.369330f, 0.399785f, -0.471419f, 0.551138f, - -0.307569f, 0.064315f, 0.311605f, 0.041736f, 0.650943f, 0.780496f}; - - const float kReference[] = {-0.173584f, -0.265778f, 0.158783f, -0.259430f, - -0.176361f, 0.192841f, 0.056854f, 0.171448f, - 0.050751f, -0.194580f, -0.208710f, 0.153717f}; - - RunBitexactnessTest( - 8000, 1, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} - -TEST(LowCutFilterBitExactnessTest, Stereo8kHzInitial) { - const float kReferenceInput[] = { - 0.790847f, 0.165037f, 0.165494f, 0.709852f, -0.930269f, 0.770840f, - -0.184538f, -0.927236f, 0.492296f, -0.690342f, -0.712183f, 0.211918f, - -0.491038f, -0.351692f, -0.196418f, -0.187253f, -0.227618f, 0.219604f, - -0.666219f, -0.623816f, -0.810742f, -0.353627f, 0.539194f, -0.531764f, - 0.480731f, 0.385637f, 0.648156f, 0.655955f, -0.413264f, -0.381262f, - 0.046060f, -0.349402f, 0.663685f, 0.620590f, 0.113997f, -0.474072f, - 0.361132f, -0.532694f, -0.087149f, -0.230866f, 0.077203f, 0.983407f, - 0.510441f, 0.960910f, -0.530435f, 0.057118f, -0.897128f, 0.513751f, - 0.203960f, 0.714337f, 0.976554f, 0.858969f, -0.180970f, -0.999317f, - 0.081757f, -0.584539f, -0.561433f, -0.348387f, -0.808101f, 0.495067f, - 0.497018f, 0.086599f, -0.323735f, 0.664667f, 0.105144f, 0.915086f, - 0.785667f, -0.286993f, 0.092804f, -0.306636f, 0.245606f, 0.593249f, - 0.491750f, -0.748928f, 0.644788f, -0.949699f, -0.171142f, 0.462815f, - 0.562748f, -0.265428f, 0.489736f, 0.784534f, -0.514793f, -0.740806f, - -0.549864f, -0.299972f, -0.425831f, 0.854976f, -0.897372f, 0.185334f, - -0.674202f, 0.676812f, -0.664878f, 0.004401f, 0.998659f, -0.289186f, - -0.905845f, -0.572679f, -0.204322f, -0.332664f, -0.540795f, 0.872240f, - 0.366378f, 0.924228f, -0.124054f, 0.880673f, -0.988331f, 0.220614f, - 0.602152f, -0.534037f, 0.864937f, 0.526526f, 0.652899f, 0.146927f, - 0.585163f, -0.341918f, -0.553076f, -0.375227f, 0.169047f, 0.659828f, - -0.419075f, -0.194891f, 0.724115f, 0.229479f, 0.982376f, -0.592602f, - 0.654418f, 0.351723f, -0.502101f, -0.048429f, -0.201850f, 0.198876f, - 0.601046f, -0.789862f, 0.642884f, 0.682173f, -0.290988f, -0.139861f, - 0.144478f, 0.401649f, 0.484940f, 0.515768f, -0.221742f, -0.141395f, - 0.912689f, 0.145943f, 0.699444f, -0.447309f, 0.244647f, 0.176723f, - 0.926937f, -0.828195f, 0.000998f, 0.043179f, -0.819668f, 0.809333f, - 0.768778f, -0.122021f, 0.563445f, -0.703070f}; - - const float kReference[] = { - 0.733307f, 0.084106f, 0.072693f, 0.566193f, -1.000000f, 0.652130f, - -0.297424f, -0.964020f, 0.438568f, -0.698364f, -0.654449f, 0.266205f, - 0.454102f, 0.684784f, -0.586823f, -0.747375f, -0.503021f, -0.222961f, - -0.314972f, 0.907196f, -0.796295f, 0.284271f, -0.533417f, 0.773956f}; - - RunBitexactnessTest( - 8000, 2, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} - -TEST(LowCutFilterBitExactnessTest, Stereo8kHzConverged) { - const float kReferenceInput[] = { - -0.502095f, -0.227154f, -0.137133f, 0.661773f, 0.649294f, -0.094003f, - -0.238880f, 0.851737f, 0.481687f, 0.475266f, 0.893832f, 0.020199f, - 0.583758f, -0.095653f, 0.698397f, -0.219138f, 0.476753f, 0.952877f, - 0.046598f, -0.140169f, -0.585684f, -0.353197f, -0.778260f, -0.249580f, - -0.340192f, -0.315790f, 0.634238f, 0.063371f, 0.042244f, 0.548619f, - -0.759474f, 0.250900f, -0.306703f, -0.330761f, 0.149233f, 0.727875f, - -0.602874f, 0.344902f, 0.803663f, -0.601686f, -0.403432f, -0.006959f, - 0.779808f, 0.002829f, -0.446010f, 0.067916f, 0.148499f, -0.174391f, - -0.970473f, 0.405530f, 0.013494f, -0.237468f, -0.870137f, -0.282840f, - -0.531498f, -0.592992f, 0.627559f, -0.213131f, -0.892850f, -0.249897f, - 0.549988f, -0.669405f, 0.824438f, -0.361588f, -0.340441f, -0.591529f, - 0.534429f, -0.860054f, 0.900068f, -0.683580f, -0.427108f, 0.374258f, - -0.717700f, 0.024173f, 0.442654f, 0.857690f, 0.464208f, 0.499696f, - -0.185361f, -0.521017f, 0.041701f, -0.561845f, 0.684776f, 0.325866f, - 0.632471f, 0.587755f, -0.061790f, -0.380950f, 0.375158f, 0.973704f, - 0.539868f, 0.659162f, 0.412170f, 0.190673f, 0.505748f, -0.006556f, - 0.730265f, -0.863945f, 0.937092f, -0.802487f, 0.093954f, -0.194060f, - -0.785920f, 0.448332f, 0.227365f, 0.565936f, 0.133241f, 0.622638f, - 0.153552f, 0.888058f, 0.742904f, 0.015204f, 0.577646f, -0.053939f, - 0.657603f, -0.355037f, 0.952293f, -0.443578f, -0.854338f, 0.502447f, - 0.662377f, 0.844676f, -0.345951f, 0.608139f, 0.076501f, -0.073410f, - 0.641501f, 0.903813f, -0.847454f, 0.417342f, -0.530147f, -0.202209f, - -0.463751f, 0.665027f, 0.990748f, 0.299502f, 0.407906f, 0.864606f, - 0.375305f, 0.136708f, -0.238305f, 0.269159f, -0.273543f, -0.184761f, - -0.262601f, -0.063202f, 0.006828f, 0.821072f, -0.587138f, -0.322793f, - 0.148251f, -0.026135f, -0.475562f, 0.159187f, 0.756655f, -0.878100f, - -0.118247f, -0.831484f, 0.126475f, 0.078621f, 0.536116f, -0.533819f, - 0.174723f, -0.082052f, 0.721963f, 0.321672f, -0.292242f, -0.305627f, - -0.492564f, 0.905056f, -0.403598f, -0.683188f, -0.277406f, 0.483258f, - 0.411800f, 0.401784f, -0.987548f, -0.251309f, 0.802991f, -0.363310f, - 0.194166f, -0.404410f, -0.749971f, -0.223289f, 0.635375f, 0.962351f, - 0.723980f, -0.832358f, -0.324576f, -0.527742f, -0.364389f, 0.968897f, - 0.096502f, 0.498503f, 0.683703f, -0.666221f, 0.806195f, -0.789752f, - 0.490186f, 0.458744f, 0.434939f, -0.733136f, -0.108422f, 0.017574f, - 0.060981f, 0.719434f, 0.355450f, 0.611677f, 0.062486f, 0.911792f, - -0.866646f, 0.083036f, -0.436679f, -0.038199f, 0.369728f, -0.583483f, - 0.216322f, -0.347648f, 0.761694f, -0.733211f, -0.795184f, 0.918234f, - -0.694196f, -0.694924f, -0.688895f, -0.820861f, -0.091151f, 0.337791f, - 0.662603f, 0.580470f, 0.425422f, -0.054805f, 0.417176f, 0.916119f, - 0.011551f, -0.389894f, 0.579622f, -0.527226f, -0.531394f, -0.070601f, - 0.238774f, 0.230659f, -0.754752f, -0.752413f, -0.431082f, 0.471466f, - -0.177384f, 0.657964f, 0.870228f, -0.201867f, -0.895577f, 0.142372f, - 0.495340f, -0.359513f, -0.014131f, -0.556694f, 0.878547f, -0.035389f, - 0.079992f, -0.557886f, -0.808110f, -0.879669f, 0.639018f, 0.542957f, - -0.608609f, 0.790236f, 0.368600f, 0.313693f, 0.980762f, -0.932616f, - -0.151493f, -0.020033f, 0.167009f, -0.833461f, 0.320309f, -0.895390f, - 0.113661f, 0.424050f, -0.024179f, 0.235201f, -0.572445f, 0.291317f, - -0.238715f, -0.792574f, -0.244977f, -0.474278f, -0.517429f, 0.245848f, - 0.045856f, -0.173525f, -0.564416f, 0.717107f, 0.722017f, -0.432122f, - 0.230786f, 0.558979f, 0.909695f, 0.839206f, -0.230369f, -0.674714f, - 0.593503f, -0.772366f, -0.682351f, -0.288344f, 0.695517f, 0.165562f, - 0.172355f, 0.851676f, 0.150157f, -0.980045f, 0.618755f, 0.217617f, - -0.040173f, -0.463120f, -0.483807f, -0.037981f, -0.545317f, -0.902795f, - -0.661516f, -0.483107f, -0.604180f, 0.211386f, 0.647407f, 0.621230f, - 0.604474f, 0.416227f, 0.718756f, 0.562169f, -0.592406f, 0.986686f, - -0.812751f, 0.301237f, -0.569647f, -0.512254f, -0.320624f, -0.604275f, - 0.013667f, 0.901516f, -0.210786f, 0.168930f, 0.213074f, 0.429286f, - -0.196927f, 0.717382f, 0.840970f, 0.501678f, -0.428817f, 0.593632f, - -0.714468f, 0.009100f, 0.221376f, 0.407593f, -0.233320f, 0.457367f, - 0.774569f, -0.888303f, -0.723567f, 0.726130f, -0.156507f, -0.177372f, - 0.918283f, 0.500491f, 0.961994f, -0.532968f, -0.807546f, -0.230836f, - 0.000545f, 0.140512f, 0.953263f, -0.014290f, -0.198234f, 0.989981f, - -0.478004f, 0.330649f, 0.928513f, 0.342302f, -0.401650f, 0.062253f, - -0.997074f, 0.767578f, -0.191232f, -0.397589f, 0.901163f, -0.078704f, - -0.424705f, -0.830747f, 0.164363f, -0.693863f, -0.853811f, 0.161130f, - -0.425970f, -0.276160f, 0.449649f, 0.716623f, -0.304169f, 0.923491f, - 0.907138f, -0.587925f, 0.536490f, 0.231064f, 0.837845f, 0.205075f, - 0.404276f, 0.487350f, -0.229795f, -0.496992f, -0.926481f, -0.055754f, - 0.290145f, -0.442060f, 0.035722f, -0.508667f, -0.404984f, 0.300948f, - 0.782787f, 0.722213f, -0.580170f, -0.201812f, 0.775766f, -0.486944f, - 0.933603f, 0.238315f, -0.669308f, 0.652398f, 0.311386f, 0.092905f, - -0.497341f, -0.919687f, -0.533249f, -0.277774f, 0.266910f, 0.972196f, - -0.585687f, 0.514168f, 0.772656f, -0.055540f, -0.682173f, 0.621842f, - -0.046984f, -0.767425f, 0.751441f, 0.270373f, -0.805437f, 0.816879f, - -0.929968f, -0.920501f, 0.977136f, 0.372363f, -0.246622f, 0.008649f, - 0.526991f, -0.902250f, 0.451855f, 0.402656f, -0.082218f, 0.164590f, - -0.321820f, -0.658749f, -0.201613f, 0.839554f, -0.547909f, -0.277987f, - -0.350876f, -0.832836f, 0.025331f, 0.665730f, 0.809227f, 0.447192f, - -0.234008f, -0.403966f, 0.383423f, 0.760914f, 0.849097f, -0.837494f, - -0.034654f, -0.743470f, -0.494178f, 0.767923f, -0.607446f, -0.757293f}; - - const float kReference[] = { - -0.544525f, 0.264221f, 0.647919f, 0.565552f, 0.496185f, 0.271332f, - 0.519958f, 0.318085f, -0.792999f, 0.733429f, -1.000000f, 0.103973f, - 0.981720f, 0.314850f, 0.476837f, 0.514252f, -0.196411f, -0.425812f, - -0.783112f, 0.101105f, 0.419739f, -0.291718f, 0.183350f, -0.332489f}; - - RunBitexactnessTest( - 8000, 2, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} - -TEST(LowCutFilterBitExactnessTest, Mono16kHzInitial) { - const float kReferenceInput[] = { - 0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f, - -0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f, - 0.202718f, -0.017621f, 0.199738f, -0.057279f, -0.034693f, 0.416303f, - 0.393761f, 0.396041f, 0.187653f, -0.337438f, 0.200436f, 0.455577f, - 0.136624f, 0.289150f, 0.203131f, -0.084798f, 0.082124f, -0.220010f, - 0.248266f, -0.320554f, -0.298701f, -0.226218f, -0.822794f, 0.401962f, - 0.090876f, -0.210968f, 0.382936f, -0.478291f, -0.028572f, -0.067474f, - 0.089204f, 0.087430f, -0.241695f, -0.008398f, -0.046076f, 0.175416f, - 0.305518f, 0.309992f, -0.241352f, 0.021618f, -0.339291f, -0.311173f, - -0.001914f, 0.428301f, -0.215087f, 0.103784f, -0.063041f, 0.312250f, - -0.304344f, 0.009098f, 0.154406f, 0.307571f, 0.431537f, 0.024014f, - -0.416832f, -0.207440f, -0.296664f, 0.656846f, -0.172033f, 0.209054f, - -0.053772f, 0.248326f, -0.213741f, -0.391871f, -0.397490f, 0.136428f, - -0.049568f, -0.054788f, 0.396633f, 0.081485f, 0.055279f, 0.443690f, - -0.224812f, 0.194675f, 0.233369f, -0.068107f, 0.060270f, -0.325801f, - -0.320801f, 0.029308f, 0.201837f, 0.722528f, -0.186366f, 0.052351f, - -0.023053f, -0.540192f, -0.122671f, -0.501532f, 0.234847f, -0.248165f, - 0.027971f, -0.152171f, 0.084820f, -0.167764f, 0.136923f, 0.206619f, - 0.478395f, -0.054249f, -0.597574f, -0.234627f, 0.378548f, -0.299619f, - 0.268543f, 0.034666f, 0.401492f, -0.547983f, -0.055248f, -0.337538f, - 0.812657f, 0.230611f, 0.385360f, -0.295713f, -0.130957f, -0.076143f, - 0.306960f, -0.077653f, 0.196049f, -0.573390f, -0.098885f, -0.230155f, - -0.440716f, 0.141956f, 0.078802f, 0.009356f, -0.372703f, 0.315083f, - 0.097859f, -0.083575f, 0.006397f, -0.073216f, -0.489105f, -0.079827f, - -0.232329f, -0.273644f, -0.323162f, -0.149105f, -0.559646f, 0.269458f, - 0.145333f, -0.005597f, -0.009717f, -0.223051f, 0.284676f, -0.037228f, - -0.199679f, 0.377651f, -0.062813f, -0.164607f}; - - const float kReference[] = {0.147160f, 0.495163f, -0.648346f, 0.234931f, - 0.075289f, -0.373779f, -0.117676f, 0.100345f, - 0.981719f, 0.714896f, -0.447357f, 0.770867f}; - - RunBitexactnessTest( - 16000, 1, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} - -TEST(LowCutFilterBitExactnessTest, Mono16kHzConverged) { - const float kReferenceInput[] = { - 0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f, - -0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f, - 0.202718f, -0.017621f, 0.199738f, -0.057279f, -0.034693f, 0.416303f, - 0.393761f, 0.396041f, 0.187653f, -0.337438f, 0.200436f, 0.455577f, - 0.136624f, 0.289150f, 0.203131f, -0.084798f, 0.082124f, -0.220010f, - 0.248266f, -0.320554f, -0.298701f, -0.226218f, -0.822794f, 0.401962f, - 0.090876f, -0.210968f, 0.382936f, -0.478291f, -0.028572f, -0.067474f, - 0.089204f, 0.087430f, -0.241695f, -0.008398f, -0.046076f, 0.175416f, - 0.305518f, 0.309992f, -0.241352f, 0.021618f, -0.339291f, -0.311173f, - -0.001914f, 0.428301f, -0.215087f, 0.103784f, -0.063041f, 0.312250f, - -0.304344f, 0.009098f, 0.154406f, 0.307571f, 0.431537f, 0.024014f, - -0.416832f, -0.207440f, -0.296664f, 0.656846f, -0.172033f, 0.209054f, - -0.053772f, 0.248326f, -0.213741f, -0.391871f, -0.397490f, 0.136428f, - -0.049568f, -0.054788f, 0.396633f, 0.081485f, 0.055279f, 0.443690f, - -0.224812f, 0.194675f, 0.233369f, -0.068107f, 0.060270f, -0.325801f, - -0.320801f, 0.029308f, 0.201837f, 0.722528f, -0.186366f, 0.052351f, - -0.023053f, -0.540192f, -0.122671f, -0.501532f, 0.234847f, -0.248165f, - 0.027971f, -0.152171f, 0.084820f, -0.167764f, 0.136923f, 0.206619f, - 0.478395f, -0.054249f, -0.597574f, -0.234627f, 0.378548f, -0.299619f, - 0.268543f, 0.034666f, 0.401492f, -0.547983f, -0.055248f, -0.337538f, - 0.812657f, 0.230611f, 0.385360f, -0.295713f, -0.130957f, -0.076143f, - 0.306960f, -0.077653f, 0.196049f, -0.573390f, -0.098885f, -0.230155f, - -0.440716f, 0.141956f, 0.078802f, 0.009356f, -0.372703f, 0.315083f, - 0.097859f, -0.083575f, 0.006397f, -0.073216f, -0.489105f, -0.079827f, - -0.232329f, -0.273644f, -0.323162f, -0.149105f, -0.559646f, 0.269458f, - 0.145333f, -0.005597f, -0.009717f, -0.223051f, 0.284676f, -0.037228f, - -0.199679f, 0.377651f, -0.062813f, -0.164607f, -0.082091f, -0.236957f, - -0.313025f, 0.705903f, 0.462637f, 0.085942f, -0.351308f, -0.241859f, - -0.049333f, 0.221165f, -0.372235f, -0.651092f, -0.404957f, 0.093201f, - 0.109366f, 0.126224f, -0.036409f, 0.051333f, -0.133063f, 0.240896f, - -0.380532f, 0.127160f, -0.237176f, -0.093586f, 0.154478f, 0.290379f, - -0.312329f, 0.352297f, 0.184480f, -0.018965f, -0.054555f, -0.060811f, - -0.084705f, 0.006440f, 0.014333f, 0.230847f, 0.426721f, 0.130481f, - -0.058605f, 0.174712f, 0.051204f, -0.287773f, 0.265265f, 0.085810f, - 0.037775f, 0.143988f, 0.073051f, -0.263103f, -0.045366f, -0.040816f, - -0.148673f, 0.470072f, -0.244727f, -0.135204f, -0.198973f, -0.328139f, - -0.053722f, -0.076590f, 0.427586f, -0.069591f, -0.297399f, 0.448094f, - 0.345037f, -0.064170f, -0.420903f, -0.124253f, -0.043578f, 0.077149f, - -0.072983f, 0.123916f, 0.109517f, -0.349508f, -0.264912f, -0.207106f, - -0.141912f, -0.089586f, 0.003485f, -0.846518f, -0.127715f, 0.347208f, - -0.298095f, 0.260935f, 0.097899f, -0.008106f, 0.050987f, -0.437362f, - -0.023625f, 0.448230f, 0.027484f, 0.011562f, -0.205167f, -0.008611f, - 0.064930f, 0.119156f, -0.104183f, -0.066078f, 0.565530f, -0.631108f, - 0.623029f, 0.094334f, 0.279472f, -0.465059f, -0.164888f, -0.077706f, - 0.118130f, -0.466746f, 0.131800f, -0.338936f, 0.018497f, 0.182304f, - 0.091398f, 0.302547f, 0.281153f, -0.181899f, 0.071836f, -0.263911f, - -0.369380f, 0.258447f, 0.000014f, -0.015347f, 0.254619f, 0.166159f, - 0.097865f, 0.349389f, 0.259834f, 0.067003f, -0.192925f, -0.182080f, - 0.333139f, -0.450434f, -0.006836f, -0.544615f, 0.285183f, 0.240811f, - 0.000325f, -0.019796f, -0.694804f, 0.162411f, -0.612686f, -0.648134f, - 0.022338f, -0.265058f, 0.114993f, 0.189185f, 0.239697f, -0.193148f, - 0.125581f, 0.028122f, 0.230849f, 0.149832f, 0.250919f, -0.036871f, - -0.041136f, 0.281627f, -0.593466f, -0.141009f, -0.355074f, -0.106915f, - 0.181276f, 0.230753f, -0.283631f, -0.131643f, 0.038292f, -0.081563f, - 0.084345f, 0.111763f, -0.259882f, -0.049416f, -0.595824f, 0.320077f, - -0.175802f, -0.336422f, -0.070966f, -0.399242f, -0.005829f, -0.156680f, - 0.608591f, 0.318150f, -0.697767f, 0.123331f, -0.390716f, -0.071276f, - 0.045943f, 0.208958f, -0.076304f, 0.440505f, -0.134400f, 0.091525f, - 0.185763f, 0.023806f, 0.246186f, 0.090323f, -0.219133f, -0.504520f, - 0.519393f, -0.168939f, 0.028884f, 0.157380f, 0.031745f, -0.252830f, - -0.130705f, -0.034901f, 0.413302f, -0.240559f, 0.219279f, 0.086246f, - -0.065353f, -0.295376f, -0.079405f, -0.024226f, -0.410629f, 0.053706f, - -0.229794f, -0.026336f, 0.093956f, -0.252810f, -0.080555f, 0.097827f, - -0.513040f, 0.289508f, 0.677527f, 0.268109f, -0.088244f, 0.119781f, - -0.289511f, 0.524778f, 0.262884f, 0.220028f, -0.244767f, 0.089411f, - -0.156018f, -0.087030f, -0.159292f, -0.286646f, -0.253953f, -0.058657f, - -0.474756f, 0.169797f, -0.032919f, 0.195384f, 0.075355f, 0.138131f, - -0.414465f, -0.285118f, -0.124915f, 0.030645f, 0.315431f, -0.081032f, - 0.352546f, 0.132860f, 0.328112f, 0.035476f, -0.183550f, -0.413984f, - 0.043452f, 0.228748f, -0.081765f, -0.151125f, -0.086251f, -0.306448f, - -0.137774f, -0.050508f, 0.012811f, -0.017824f, 0.170841f, 0.030549f, - 0.506935f, 0.087197f, 0.504274f, -0.202080f, 0.147146f, -0.072728f, - 0.167713f, 0.165977f, -0.610894f, -0.370849f, -0.402698f, 0.112297f, - 0.410855f, -0.091330f, 0.227008f, 0.152454f, -0.293884f, 0.111074f, - -0.210121f, 0.423728f, -0.009101f, 0.457188f, -0.118785f, 0.164720f, - -0.017547f, -0.565046f, -0.274461f, 0.171169f, -0.015338f, -0.312635f, - -0.175044f, 0.069729f, -0.277504f, 0.272454f, -0.179049f, 0.505495f, - -0.301774f, 0.055664f, -0.425058f, -0.202222f, -0.165787f, 0.112155f, - 0.263284f, 0.083972f, -0.104256f, 0.227892f, 0.223253f, 0.033592f, - 0.159638f, 0.115358f, -0.275811f, 0.212265f, -0.183658f, -0.168768f}; - - const float kReference[] = {-0.248962f, -0.088257f, 0.083041f, -0.037323f, - 0.127659f, 0.149388f, -0.220978f, -0.004242f, - -0.538544f, 0.384289f, -0.117615f, -0.268524f}; - - RunBitexactnessTest( - 16000, 1, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} - -TEST(LowCutFilterBitExactnessTest, Stereo16kHzInitial) { - const float kReferenceInput[] = { - 0.087390f, -0.370759f, -0.235918f, 0.583079f, 0.678359f, 0.360473f, - -0.166156f, 0.285780f, -0.571837f, 0.234542f, 0.350382f, 0.202047f, - -0.307381f, -0.271197f, -0.657038f, 0.590723f, -0.014666f, -0.290754f, - 0.550122f, -0.526390f, 0.689667f, 0.633054f, 0.692457f, -0.259626f, - -0.233541f, 0.722669f, -0.072182f, 0.141096f, 0.390614f, 0.921835f, - 0.092626f, 0.273153f, 0.141785f, 0.854224f, 0.727531f, -0.660321f, - -0.642602f, -0.512991f, 0.503559f, -0.601731f, 0.965881f, 0.419277f, - -0.649128f, 0.716595f, 0.818823f, 0.923326f, 0.141199f, 0.125758f, - -0.646678f, 0.027358f, 0.096944f, -0.669445f, -0.012214f, 0.070235f, - -0.602386f, 0.246338f, -0.947369f, -0.362418f, 0.065999f, -0.346453f, - 0.204381f, -0.276135f, -0.730159f, 0.827627f, 0.281118f, 0.317548f, - 0.350661f, 0.489115f, 0.684355f, 0.033314f, -0.696263f, -0.238671f, - 0.642039f, -0.657271f, -0.340049f, 0.932944f, 0.612585f, -0.555624f, - 0.999546f, -0.872523f, -0.149034f, -0.191324f, -0.199414f, -0.776155f, - -0.151378f, 0.227092f, 0.976123f, -0.560198f, -0.291838f, -0.467516f, - -0.417004f, -0.623221f, -0.954281f, -0.101192f, -0.512720f, 0.737453f, - 0.057222f, 0.828270f, 0.947860f, 0.170852f, -0.762049f, 0.853065f, - 0.187122f, 0.767231f, -0.151048f, 0.214515f, -0.858473f, 0.849545f, - 0.284159f, -0.791001f, 0.400450f, -0.208391f, -0.830190f, -0.571042f, - -0.502402f, -0.546694f, 0.406009f, 0.508305f, 0.094573f, 0.106967f, - 0.261146f, 0.970914f, 0.268556f, 0.200911f, 0.818374f, 0.141673f, - -0.329160f, 0.914278f, -0.120154f, 0.203085f, 0.440525f, 0.357557f, - -0.574482f, -0.836753f, -0.451041f, 0.735037f, 0.118714f, -0.070744f, - -0.139398f, 0.547972f, 0.307841f, 0.315459f, -0.677958f, -0.135246f, - 0.010172f, -0.249335f, -0.039256f, -0.315157f, 0.554293f, -0.232112f, - 0.423113f, -0.038133f, 0.458360f, 0.875118f, 0.034509f, 0.806137f, - -0.563615f, 0.746439f, -0.834614f, -0.069193f, -0.956140f, 0.616561f, - -0.641581f, -0.669216f, -0.636793f, 0.382873f, -0.572473f, -0.403790f, - 0.536670f, 0.002300f, 0.818930f, -0.884294f, -0.126496f, 0.144509f, - 0.130134f, 0.647633f, -0.747802f, -0.399766f, -0.995756f, 0.902215f, - 0.532599f, 0.502608f, -0.722270f, -0.301361f, -0.697319f, -0.006559f, - 0.617305f, 0.265738f, 0.376803f, 0.279140f, 0.458643f, 0.719691f, - 0.253911f, -0.638817f, 0.146613f, -0.672868f, 0.812103f, -0.845314f, - -0.322931f, 0.161235f, -0.049530f, 0.610641f, 0.061556f, -0.545379f, - 0.418970f, -0.702735f, 0.316232f, 0.267965f, -0.541387f, -0.635544f, - -0.667295f, -0.700786f, -0.594505f, 0.909918f, -0.968183f, 0.915029f, - -0.948615f, 0.942221f, -0.404809f, 0.050146f, 0.724678f, 0.792810f, - -0.621979f, 0.321439f, 0.882462f, 0.951414f, -0.784129f, -0.642202f, - 0.493103f, -0.901063f, -0.857430f, -0.021749f, 0.699788f, 0.994083f, - -0.991215f, 0.085215f, 0.722696f, 0.818278f, 0.690701f, 0.757746f, - 0.492364f, -0.765021f, 0.018045f, -0.662336f, 0.662223f, 0.856022f, - -0.661031f, 0.767475f, -0.224274f, -0.234861f, -0.457094f, 0.735766f, - 0.483005f, -0.104255f, 0.419278f, 0.888663f, -0.651764f, -0.510807f, - 0.281858f, 0.617225f, 0.706742f, -0.203765f, -0.769012f, -0.839438f, - -0.279065f, 0.657811f, -0.570781f, 0.582081f, 0.309377f, -0.947707f, - 0.571553f, 0.845126f, -0.015374f, 0.668023f, -0.737293f, 0.519567f, - 0.851472f, 0.665415f, -0.481198f, -0.573956f, 0.044630f, -0.205286f, - -0.041780f, 0.987807f, 0.208957f, 0.889817f, -0.019116f, -0.124107f, - 0.545311f, 0.488133f, -0.114192f, -0.894000f, -0.824356f, 0.595972f, - 0.311165f, -0.935329f, 0.114134f, 0.439603f, -0.779184f, -0.566705f, - 0.622040f, -0.722676f, 0.763798f, 0.847112f, -0.974489f, -0.245681f, - -0.664377f, 0.080446f, -0.796675f, -0.921465f, 0.866458f, 0.943184f, - -0.278144f, 0.288411f, -0.864105f, -0.584176f, -0.920792f, -0.061281f, - -0.699807f, 0.982614f}; - - const float kReference[] = { - 0.085604f, -0.367126f, -0.218170f, 0.594653f, 0.661245f, 0.319041f, - -0.212891f, 0.237800f, -0.614716f, 0.201758f, 0.305032f, 0.144414f, - -0.936523f, 0.647359f, -0.613403f, -0.611542f, -0.549835f, 0.477004f, - -0.477386f, -0.287262f, 0.650746f, 0.101169f, 0.899258f, -0.808014f}; - - RunBitexactnessTest( - 16000, 2, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} - -TEST(LowCutFilterBitExactnessTest, Stereo16kHzConverged) { - const float kReferenceInput[] = { - -0.145875f, 0.910744f, 0.448494f, 0.161783f, 0.080516f, 0.410882f, - -0.989942f, 0.565032f, 0.853719f, -0.983409f, 0.649257f, 0.534672f, - 0.994274f, -0.544694f, 0.839084f, 0.283999f, -0.789360f, -0.463678f, - 0.527688f, 0.611020f, -0.791494f, -0.060482f, -0.561876f, 0.845416f, - -0.359355f, 0.715088f, -0.480307f, 0.756126f, -0.623465f, 0.518388f, - -0.936621f, 0.284678f, 0.133742f, -0.247181f, -0.574903f, 0.584314f, - -0.709113f, -0.021715f, -0.974309f, -0.626776f, -0.029539f, 0.676452f, - -0.717886f, 0.464434f, 0.382134f, -0.931015f, -0.022285f, 0.942781f, - -0.775097f, 0.486428f, 0.277083f, 0.188366f, -0.002755f, 0.135705f, - -0.146991f, -0.847521f, -0.418827f, 0.122670f, 0.266667f, 0.861552f, - 0.955538f, -0.812807f, 0.323470f, 0.205546f, -0.052364f, -0.287487f, - -0.048843f, 0.342044f, 0.919290f, -0.821831f, 0.595485f, 0.181551f, - 0.824394f, -0.797741f, -0.413411f, -0.896824f, 0.008256f, 0.536752f, - -0.434029f, -0.549280f, -0.337421f, -0.093497f, 0.474769f, 0.019771f, - -0.234972f, 0.810966f, 0.930515f, 0.256535f, -0.735938f, 0.236604f, - -0.233960f, 0.982387f, -0.426345f, 0.412383f, 0.070412f, -0.613578f, - 0.378870f, -0.899090f, -0.631132f, -0.908683f, 0.770083f, 0.679589f, - -0.763690f, -0.179170f, -0.759543f, 0.144185f, 0.898780f, -0.487230f, - 0.979731f, -0.300384f, -0.582955f, 0.331654f, 0.946689f, 0.245400f, - -0.872924f, -0.252981f, -0.667497f, -0.537444f, -0.895583f, 0.803513f, - 0.586583f, -0.253971f, 0.664109f, 0.507669f, 0.243726f, -0.211814f, - -0.281444f, -0.822295f, -0.316646f, 0.097341f, -0.078905f, 0.290905f, - 0.027042f, 0.628853f, -0.805634f, -0.072573f, 0.179635f, -0.625656f, - 0.222660f, -0.896116f, 0.151454f, 0.684689f, -0.000548f, -0.121950f, - -0.701886f, -0.943441f, 0.513340f, 0.592212f, -0.412889f, -0.769587f, - -0.249817f, 0.657787f, 0.683553f, 0.330477f, 0.920280f, 0.886236f, - -0.774601f, 0.296575f, -0.038392f, -0.866959f, 0.795542f, -0.005540f, - 0.542607f, -0.879276f, -0.475085f, 0.302139f, -0.732792f, 0.277091f, - -0.230114f, 0.531396f, 0.305831f, -0.237022f, -0.399963f, -0.319721f, - 0.837853f, -0.087466f, -0.115006f, -0.091628f, 0.890564f, -0.561762f, - 0.764806f, -0.960249f, -0.316470f, 0.532055f, -0.314393f, 0.237613f, - -0.093958f, -0.979675f, 0.198162f, 0.203137f, 0.298835f, -0.314559f, - -0.013401f, 0.403548f, 0.775605f, -0.889884f, -0.803276f, 0.299566f, - 0.528142f, 0.975918f, -0.749350f, -0.271046f, 0.352460f, -0.248484f, - 0.726917f, -0.416046f, -0.733050f, 0.345301f, -0.594830f, 0.737030f, - 0.502315f, -0.161241f, -0.999538f, -0.701073f, -0.452331f, 0.744850f, - 0.202502f, -0.357623f, -0.431414f, -0.129368f, 0.807518f, 0.850211f, - 0.010585f, 0.255164f, 0.438528f, -0.952174f, 0.149865f, -0.906931f, - -0.154937f, -0.064531f, -0.954744f, -0.869852f, 0.847913f, 0.068286f, - -0.266407f, -0.272108f, -0.697253f, -0.700783f, -0.298396f, -0.328068f, - 0.568056f, -0.026522f, -0.070404f, -0.737495f, 0.772783f, 0.349115f, - 0.670319f, 0.312976f, 0.967834f, 0.959580f, -0.499694f, 0.249141f, - 0.456485f, -0.003659f, 0.699657f, -0.618164f, -0.751712f, -0.994419f, - -0.694094f, 0.068322f, 0.021267f, -0.229568f, -0.378807f, -0.992889f, - 0.630485f, 0.276837f, -0.103321f, -0.511828f, 0.606770f, 0.647942f, - 0.704381f, -0.065496f, 0.941398f, 0.682488f, -0.842904f, -0.524802f, - 0.635142f, -0.188343f, -0.067376f, 0.903072f, 0.930011f, 0.530570f, - 0.149067f, 0.831850f, -0.009135f, -0.667975f, -0.348005f, -0.407128f, - 0.116597f, -0.865046f, -0.862044f, -0.666431f, 0.894877f, 0.622177f, - 0.420911f, 0.940491f, 0.996854f, 0.974910f, -0.699827f, 0.916958f, - 0.060918f, -0.851827f, -0.376358f, 0.790342f, 0.669537f, -0.995302f, - 0.280420f, 0.606365f, -0.509738f, -0.871756f, -0.473703f, -0.794559f, - -0.032562f, -0.162231f, -0.237422f, 0.773530f, -0.158885f, -0.432304f, - -0.903638f, -0.561668f, -0.521648f, -0.941483f, 0.404622f, -0.984729f, - 0.221841f, -0.183821f, -0.502107f, 0.304919f, -0.359446f, -0.792656f, - 0.071130f, -0.670260f, 0.766877f, 0.332914f, 0.695485f, 0.525322f, - 0.614028f, 0.265905f, 0.420855f, 0.377327f, -0.358104f, 0.063297f, - 0.746388f, -0.890921f, 0.000802f, -0.134474f, 0.808565f, 0.260367f, - 0.966072f, 0.170401f, 0.681273f, -0.062372f, 0.090445f, -0.641792f, - 0.268923f, 0.925918f, 0.068028f, -0.040771f, 0.587332f, -0.814573f, - 0.761599f, -0.992253f, 0.023058f, 0.356927f, 0.131495f, -0.043083f, - -0.358974f, 0.203160f, 0.826305f, 0.365036f, 0.893467f, -0.801822f, - 0.022058f, -0.779743f, 0.090524f, 0.377572f, -0.705166f, 0.555122f, - -0.201898f, 0.796600f, -0.385912f, -0.877898f, -0.561058f, -0.834334f, - 0.900791f, -0.967259f, -0.770663f, -0.975180f, -0.567545f, -0.977145f, - 0.284899f, 0.033982f, -0.508916f, -0.612505f, -0.818259f, -0.263117f, - -0.984414f, 0.205403f, -0.042291f, -0.383765f, 0.488889f, 0.678699f, - -0.475136f, 0.028476f, -0.106452f, -0.317578f, 0.678284f, 0.964985f, - 0.252929f, -0.637450f, -0.753966f, 0.159937f, -0.342928f, -0.463627f, - 0.100478f, -0.638966f, 0.356984f, -0.888623f, -0.931886f, -0.426963f, - -0.845220f, 0.801145f, 0.693212f, -0.208603f, -0.661569f, -0.139095f, - -0.167564f, 0.457527f, -0.187053f, 0.903615f, 0.823970f, 0.902829f, - -0.307998f, -0.419512f, 0.773402f, -0.579938f, -0.738247f, 0.041032f, - 0.810925f, -0.194940f, -0.568477f, -0.842521f, 0.866120f, 0.205743f, - -0.245016f, 0.329863f, 0.584381f, -0.333016f, 0.385318f, -0.592369f, - 0.917427f, 0.423665f, -0.666187f, -0.114446f, 0.265987f, 0.859934f, - 0.058662f, 0.252949f, 0.361638f, 0.846395f, -0.694332f, -0.188558f, - -0.375048f, 0.387798f, 0.781376f, -0.018658f, 0.611647f, -0.347122f, - 0.099758f, -0.222431f, 0.793658f, 0.352240f, 0.656794f, -0.779822f, - -0.441545f, 0.535272f, -0.567887f, -0.931876f, -0.126896f, 0.873727f, - -0.475822f, 0.139491f, -0.280894f, -0.946323f, 0.000838f, 0.654030f, - -0.482035f, -0.908230f, -0.507057f, 0.321464f, -0.341181f, 0.318992f, - -0.973992f, 0.436136f, -0.217762f, -0.932989f, -0.187969f, 0.432615f, - 0.842673f, 0.968031f, 0.966842f, 0.792612f, 0.731406f, 0.601922f, - 0.109958f, -0.162256f, -0.745755f, 0.309241f, 0.727930f, -0.450803f, - 0.680328f, -0.858490f, -0.242416f, -0.463661f, -0.694158f, 0.261999f, - -0.367250f, 0.918224f, -0.002652f, 0.477217f, -0.974489f, 0.210706f, - 0.152903f, 0.614758f, 0.309936f, 0.756457f, 0.804746f, -0.695534f, - -0.614840f, 0.581951f, -0.878590f, -0.220346f, -0.400068f, 0.468360f, - -0.791581f, 0.585151f, 0.565458f, 0.064795f, -0.493295f, -0.858091f, - 0.251607f, -0.950637f, -0.875915f, -0.740776f, -0.098772f, 0.344672f, - 0.712222f, -0.003109f, -0.902431f, -0.372335f, 0.283262f, 0.572773f, - -0.421699f, -0.004264f, 0.636869f, 0.190257f, 0.072849f, -0.338254f, - -0.176620f, 0.588012f, -0.313584f, -0.074787f, -0.264353f, 0.359141f, - 0.135558f, 0.303554f, -0.017773f, -0.203084f, -0.045032f, -0.866825f, - -0.177943f, 0.938184f, 0.561442f, 0.458036f, 0.531301f, 0.513162f, - 0.686541f, 0.540314f, 0.957322f, -0.777281f, -0.207846f, -0.015879f, - -0.483811f, -0.926068f, 0.948763f, 0.452852f, -0.704070f, -0.704211f, - 0.409648f, -0.238013f, -0.847177f, -0.178319f, -0.714019f, 0.597840f, - 0.860496f, -0.990561f, 0.300081f, 0.357065f, -0.492754f, 0.686362f, - -0.412082f, -0.946279f, -0.813386f, 0.595770f, 0.422805f, 0.566814f, - 0.247845f, 0.650831f, -0.929955f, -0.189050f, -0.500662f, -0.038206f, - 0.761678f, -0.438630f, 0.198285f, -0.947548f, -0.689603f, 0.667822f, - -0.610213f, 0.659576f, -0.323850f, 0.342233f, -0.895267f, 0.468618f, - -0.001036f, 0.886600f, -0.420455f, -0.246879f, -0.772489f, 0.929701f, - -0.134977f, -0.830874f, 0.433353f, 0.013575f, -0.343825f, 0.507048f, - 0.672012f, -0.492567f, 0.068850f, -0.129670f, -0.684592f, 0.200962f, - 0.874902f, -0.784483f, 0.799963f, 0.100930f, -0.145287f, -0.695238f, - -0.504908f, -0.105262f, 0.065567f, -0.290698f, 0.546230f, 0.763362f, - 0.468184f, -0.187136f, 0.208357f, 0.282210f, -0.745066f, -0.007616f, - -0.379061f, 0.157149f, 0.887218f, -0.146121f, -0.933743f, 0.858868f, - 0.849965f, -0.283386f, -0.480022f, 0.573719f, 0.023164f, 0.125054f, - 0.369588f, -0.815207f, 0.745158f, 0.885876f, -0.806812f, 0.691765f, - 0.818791f, -0.977318f, 0.047365f, 0.300691f, -0.229709f, 0.298604f, - 0.525707f, 0.151372f, 0.263838f, -0.443592f, 0.679673f, -0.146330f, - 0.263245f, 0.666934f, -0.459629f, -0.198399f, 0.108509f, -0.112269f, - -0.819232f, 0.488763f, -0.934769f, -0.140515f, -0.925475f, 0.951596f, - 0.044680f, 0.819260f, -0.233504f, 0.768904f, -0.489965f, 0.818100f, - 0.789121f, -0.202966f, 0.250040f, 0.135195f, 0.789024f, -0.571668f, - -0.992282f, 0.761163f, -0.529757f, -0.510271f, 0.281834f, -0.390951f, - 0.651242f, 0.767377f, 0.890746f, -0.218409f, 0.602640f, -0.685773f, - 0.250331f, 0.397971f, -0.828262f, 0.062359f, 0.777133f, -0.472668f, - -0.530429f, 0.679314f, -0.008920f, -0.695267f, -0.538464f, 0.315908f, - 0.125897f, -0.416343f, 0.244610f, 0.431811f, -0.438538f, -0.175454f, - -0.275589f, 0.562784f, -0.729026f, 0.804139f, -0.420728f, -0.000884f, - 0.567181f, 0.354124f, -0.700377f, 0.393239f, -0.741974f, 0.891893f, - 0.772824f, 0.030009f, 0.358817f, 0.953587f, -0.749079f, 0.504486f, - 0.654104f, 0.562861f, -0.618235f, -0.142717f, -0.971087f, -0.349429f, - -0.730596f, -0.098965f, 0.144550f, 0.584047f, -0.160527f, 0.065073f, - 0.851409f, 0.798164f, 0.089667f, 0.802248f, -0.896347f, 0.617205f, - -0.330191f, -0.542634f, 0.644804f, -0.303531f, -0.669059f, -0.943733f, - 0.910740f, 0.360581f, 0.721124f, 0.878187f, 0.360388f, 0.834847f, - -0.486617f, 0.771236f, 0.840086f, -0.399873f, -0.853218f, 0.534797f, - -0.830096f, 0.457528f, -0.104221f, 0.302497f, -0.660996f, 0.062898f, - 0.267602f, -0.971808f, -0.059257f, 0.772652f, -0.771943f, -0.114918f, - 0.319096f, -0.410454f, 0.900737f, 0.388572f, -0.586387f, 0.109525f, - 0.758557f, 0.115715f, 0.504668f, 0.789802f, 0.683688f, -0.738287f, - -0.621692f, -0.692720f, -0.942196f, -0.981830f, 0.192903f, 0.218099f, - 0.837847f, 0.467149f, -0.397706f, -0.008851f, -0.483674f, 0.465709f, - -0.766478f, 0.492083f, 0.619578f, 0.490467f, -0.325713f, 0.168650f, - -0.062096f, -0.825470f, 0.657435f, 0.371889f, -0.465350f, 0.938967f, - -0.632452f, -0.400118f, -0.177630f, -0.527022f, -0.609889f, 0.410759f, - -0.638903f, 0.044666f, -0.407656f, -0.074436f, 0.850465f, -0.568222f, - -0.997982f, 0.813212f, 0.360084f, 0.029904f, 0.044138f, -0.794163f, - 0.993761f, -0.282062f, 0.250485f, -0.213267f, -0.984675f, 0.090570f, - 0.018221f, -0.506442f, -0.909209f, 0.683459f, -0.903500f, -0.367359f, - 0.566839f, 0.944800f, 0.172928f, 0.556088f, 0.455395f, 0.301974f, - 0.329230f, 0.877560f, 0.070163f, -0.203120f, 0.340915f, -0.118931f, - -0.734252f, -0.121593f, 0.095285f, -0.209727f, -0.203456f, 0.502697f, - 0.044701f, -0.019134f, -0.822642f, -0.498297f, -0.104882f, 0.275922f, - 0.418891f, 0.985240f, 0.864390f, -0.815541f, 0.907080f, -0.674409f, - 0.940910f, 0.194013f, -0.519546f, -0.859410f, -0.399918f, 0.627090f, - -0.846580f, -0.291054f, -0.735978f, -0.683641f, -0.875706f, 0.403687f, - -0.827037f, 0.233574f, -0.652457f, 0.302802f, -0.002607f, -0.430979f, - 0.661119f, 0.636720f, 0.876339f, -0.999348f, 0.280778f, -0.985289f, - -0.787158f, -0.786411f, -0.265782f, -0.520785f, -0.307720f, -0.500760f, - -0.225871f, -0.157923f, 0.280155f, 0.575106f, -0.460011f, 0.687965f, - 0.480937f, 0.652204f, -0.635616f, -0.869128f, 0.220701f, 0.403106f, - -0.776765f, -0.808353f, 0.195668f, 0.624465f, 0.629156f, -0.821126f, - 0.462557f, 0.807713f, -0.095536f, -0.858625f, -0.517444f, 0.463730f}; - - const float kReference[] = { - -0.816559f, 0.085419f, 0.739655f, -0.922089f, 0.669312f, -0.048218f, - -0.290039f, -0.818085f, -0.596039f, -0.177856f, -0.002197f, -0.350647f, - -0.064331f, 0.337280f, -0.621765f, 0.115906f, 0.311890f, -0.915924f, - 0.020477f, 0.836029f, -0.714020f, -0.037140f, 0.391113f, -0.340118f}; - - RunBitexactnessTest( - 16000, 2, CreateVector(rtc::ArrayView(kReferenceInput)), - CreateVector(rtc::ArrayView(kReference))); -} -} // namespace webrtc diff --git a/modules/audio_processing/utility/BUILD.gn b/modules/audio_processing/utility/BUILD.gn index 0ba0f5b060..80b2bde5bc 100644 --- a/modules/audio_processing/utility/BUILD.gn +++ b/modules/audio_processing/utility/BUILD.gn @@ -8,6 +8,17 @@ import("../../../webrtc.gni") +rtc_source_set("cascaded_biquad_filter") { + sources = [ + "cascaded_biquad_filter.cc", + "cascaded_biquad_filter.h", + ] + deps = [ + "../../../api:array_view", + "../../../rtc_base:checks", + ] +} + rtc_source_set("block_mean_calculator") { sources = [ "block_mean_calculator.cc", @@ -88,6 +99,20 @@ rtc_source_set("pffft_wrapper") { } if (rtc_include_tests) { + rtc_source_set("cascaded_biquad_filter_unittest") { + testonly = true + + sources = [ + "cascaded_biquad_filter_unittest.cc", + ] + deps = [ + ":cascaded_biquad_filter", + "../../../rtc_base:rtc_base_approved", + "../../../test:test_support", + "//testing/gtest", + ] + } + rtc_source_set("block_mean_calculator_unittest") { testonly = true diff --git a/modules/audio_processing/aec3/cascaded_biquad_filter.cc b/modules/audio_processing/utility/cascaded_biquad_filter.cc similarity index 91% rename from modules/audio_processing/aec3/cascaded_biquad_filter.cc rename to modules/audio_processing/utility/cascaded_biquad_filter.cc index 5dfd7c54e2..08b9464387 100644 --- a/modules/audio_processing/aec3/cascaded_biquad_filter.cc +++ b/modules/audio_processing/utility/cascaded_biquad_filter.cc @@ -7,7 +7,7 @@ * 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/cascaded_biquad_filter.h" +#include "modules/audio_processing/utility/cascaded_biquad_filter.h" #include @@ -53,10 +53,14 @@ CascadedBiQuadFilter::BiQuad::BiQuad( coefficients.a[1] = p_r * p_r + p_i * p_i; } +void CascadedBiQuadFilter::BiQuad::BiQuad::Reset() { + x[0] = x[1] = y[0] = y[1] = 0.f; +} + CascadedBiQuadFilter::CascadedBiQuadFilter( const CascadedBiQuadFilter::BiQuadCoefficients& coefficients, size_t num_biquads) - : biquads_(num_biquads, coefficients) {} + : biquads_(num_biquads, BiQuad(coefficients)) {} CascadedBiQuadFilter::CascadedBiQuadFilter( const std::vector& biquad_params) { @@ -85,6 +89,12 @@ void CascadedBiQuadFilter::Process(rtc::ArrayView y) { } } +void CascadedBiQuadFilter::Reset() { + for (auto& biquad : biquads_) { + biquad.Reset(); + } +} + void CascadedBiQuadFilter::ApplyBiQuad(rtc::ArrayView x, rtc::ArrayView y, CascadedBiQuadFilter::BiQuad* biquad) { diff --git a/modules/audio_processing/aec3/cascaded_biquad_filter.h b/modules/audio_processing/utility/cascaded_biquad_filter.h similarity index 75% rename from modules/audio_processing/aec3/cascaded_biquad_filter.h rename to modules/audio_processing/utility/cascaded_biquad_filter.h index 34085f1502..120b52aa57 100644 --- a/modules/audio_processing/aec3/cascaded_biquad_filter.h +++ b/modules/audio_processing/utility/cascaded_biquad_filter.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_PROCESSING_AEC3_CASCADED_BIQUAD_FILTER_H_ -#define MODULES_AUDIO_PROCESSING_AEC3_CASCADED_BIQUAD_FILTER_H_ +#ifndef MODULES_AUDIO_PROCESSING_UTILITY_CASCADED_BIQUAD_FILTER_H_ +#define MODULES_AUDIO_PROCESSING_UTILITY_CASCADED_BIQUAD_FILTER_H_ #include @@ -17,7 +17,6 @@ #include #include "api/array_view.h" -#include "rtc_base/constructor_magic.h" namespace webrtc { @@ -30,7 +29,7 @@ class CascadedBiQuadFilter { std::complex pole, float gain, bool mirror_zero_along_i_axis = false); - BiQuadParam(const BiQuadParam&); + explicit BiQuadParam(const BiQuadParam&); std::complex zero; std::complex pole; float gain; @@ -43,9 +42,10 @@ class CascadedBiQuadFilter { }; struct BiQuad { - BiQuad(const BiQuadCoefficients& coefficients) + explicit BiQuad(const BiQuadCoefficients& coefficients) : coefficients(coefficients), x(), y() {} - BiQuad(const CascadedBiQuadFilter::BiQuadParam& param); + explicit BiQuad(const CascadedBiQuadFilter::BiQuadParam& param); + void Reset(); BiQuadCoefficients coefficients; float x[2]; float y[2]; @@ -54,13 +54,18 @@ class CascadedBiQuadFilter { CascadedBiQuadFilter( const CascadedBiQuadFilter::BiQuadCoefficients& coefficients, size_t num_biquads); - CascadedBiQuadFilter( + explicit CascadedBiQuadFilter( const std::vector& biquad_params); ~CascadedBiQuadFilter(); + CascadedBiQuadFilter(const CascadedBiQuadFilter&) = delete; + CascadedBiQuadFilter& operator=(const CascadedBiQuadFilter&) = delete; + // Applies the biquads on the values in x in order to form the output in y. void Process(rtc::ArrayView x, rtc::ArrayView y); // Applies the biquads on the values in y in an in-place manner. void Process(rtc::ArrayView y); + // Resets the filter to its initial state. + void Reset(); private: void ApplyBiQuad(rtc::ArrayView x, @@ -68,10 +73,8 @@ class CascadedBiQuadFilter { CascadedBiQuadFilter::BiQuad* biquad); std::vector biquads_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CascadedBiQuadFilter); }; } // namespace webrtc -#endif // MODULES_AUDIO_PROCESSING_AEC3_CASCADED_BIQUAD_FILTER_H_ +#endif // MODULES_AUDIO_PROCESSING_UTILITY_CASCADED_BIQUAD_FILTER_H_ diff --git a/modules/audio_processing/aec3/cascaded_biquad_filter_unittest.cc b/modules/audio_processing/utility/cascaded_biquad_filter_unittest.cc similarity index 92% rename from modules/audio_processing/aec3/cascaded_biquad_filter_unittest.cc rename to modules/audio_processing/utility/cascaded_biquad_filter_unittest.cc index 57f4b04f5f..88a31ba7a9 100644 --- a/modules/audio_processing/aec3/cascaded_biquad_filter_unittest.cc +++ b/modules/audio_processing/utility/cascaded_biquad_filter_unittest.cc @@ -70,6 +70,23 @@ TEST(CascadedBiquadFilter, HighPassConfiguration) { } } +// Verifies that the reset functionality works as intended. +TEST(CascadedBiquadFilter, HighPassConfiguration) { + CascadedBiQuadFilter filter(kHighPassFilterCoefficients, 2); + + std::vector values1(100, 1.f); + filter.Process(values1); + + filter.Reset(); + + std::vector values2(100, 1.f); + filter.Process(values2); + + for (size_t k = 0; k < values1.size(); ++k) { + EXPECT_EQ(values1[k], values2[k]); + } +} + // Verifies that the filter is able to produce a transparent effect with no // impact on the data when the proper coefficients are applied. The test also // verifies that the non-in-place Process API call works as intended. diff --git a/resources/audio_processing/output_data_fixed.pb.sha1 b/resources/audio_processing/output_data_fixed.pb.sha1 index e4444a92ff..0eb2da5c5b 100644 --- a/resources/audio_processing/output_data_fixed.pb.sha1 +++ b/resources/audio_processing/output_data_fixed.pb.sha1 @@ -1 +1 @@ -91f6018874f4cbce414918d053e1d6c36d3e51c4 \ No newline at end of file +e540fa8940b41d0cda26cdef937be3a455a04be7 \ No newline at end of file diff --git a/resources/audio_processing/output_data_float.pb.sha1 b/resources/audio_processing/output_data_float.pb.sha1 index a8b35f8f53..624d609071 100644 --- a/resources/audio_processing/output_data_float.pb.sha1 +++ b/resources/audio_processing/output_data_float.pb.sha1 @@ -1 +1 @@ -4794107799631a85c4aa4671979c6fa7edbef08b \ No newline at end of file +2811f534082857ac9b9447a3e53028ef11851052 \ No newline at end of file