Use the AEC3 high-pass filter for the whole APM

This CL removes and replaces the legacy fixed-point high-pass filter in
APM with the floating point high-pass filter in AEC3.

Bug: webrtc:10907
Change-Id: I88cf8f622ab139e4ffa97f89a72425aa3becfc58
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/150103
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28950}
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index e4df10b..c8a9dbc 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -87,6 +87,24 @@
   ]
 }
 
+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 @@
     "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 @@
     ":config",
     ":gain_control_config_proxy",
     ":gain_control_interface",
+    ":high_pass_filter",
     ":noise_suppression_proxy",
     "../../api:array_view",
     "../../api:function_view",
@@ -384,6 +401,7 @@
     ]
     deps = [
       ":api",
+      ":audio_buffer",
       ":audio_processing",
       ":audio_processing_statistics",
       "../../test:test_support",
@@ -445,6 +463,7 @@
       ":config",
       ":file_audio_generator_unittests",
       ":gain_control_config_proxy",
+      ":high_pass_filter",
       ":mocks",
       "../../api:array_view",
       "../../api:scoped_refptr",
@@ -522,8 +541,8 @@
         "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 50eef88..61c6f1e 100644
--- a/modules/audio_processing/aec3/BUILD.gn
+++ b/modules/audio_processing/aec3/BUILD.gn
@@ -30,8 +30,6 @@
     "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 @@
   deps = [
     "..:apm_logging",
     "..:audio_buffer",
+    "..:high_pass_filter",
     "../../../api:array_view",
     "../../../api/audio:aec3_config",
     "../../../api/audio:echo_control",
@@ -141,6 +140,7 @@
     "../../../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 @@
       "..:audio_buffer",
       "..:audio_processing",
       "..:audio_processing_unittests",
+      "..:high_pass_filter",
       "../../../api:array_view",
       "../../../api/audio:aec3_config",
       "../../../rtc_base:checks",
@@ -176,6 +177,7 @@
       "../../../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 @@
         "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 2eff6a1..8215736 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 a505014..9dd6b19 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 952f5e7..c2ad56b 100644
--- a/modules/audio_processing/aec3/echo_canceller3.cc
+++ b/modules/audio_processing/aec3/echo_canceller3.cc
@@ -13,6 +13,7 @@
 #include <utility>
 
 #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 @@
   block_processor->BufferRender(*block);
 }
 
-void CopyBufferIntoFrame(AudioBuffer* buffer,
+void CopyBufferIntoFrame(const AudioBuffer& buffer,
                          size_t num_bands,
                          size_t frame_length,
                          std::vector<std::vector<float>>* 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<float> buffer_view(&buffer->split_bands(0)[k][0],
-                                      frame_length);
+    rtc::ArrayView<const float> 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 @@
   RenderWriter(ApmDataDumper* data_dumper,
                SwapQueue<std::vector<std::vector<float>>,
                          Aec3RenderQueueItemVerifier>* render_transfer_queue,
-               std::unique_ptr<CascadedBiQuadFilter> 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<CascadedBiQuadFilter> render_highpass_filter_;
+  HighPassFilter high_pass_filter_;
   std::vector<std::vector<float>> render_queue_input_frame_;
   SwapQueue<std::vector<std::vector<float>>, Aec3RenderQueueItemVerifier>*
       render_transfer_queue_;
@@ -179,7 +167,6 @@
     ApmDataDumper* data_dumper,
     SwapQueue<std::vector<std::vector<float>>, Aec3RenderQueueItemVerifier>*
         render_transfer_queue,
-    std::unique_ptr<CascadedBiQuadFilter> render_highpass_filter,
     int sample_rate_hz,
     int frame_length,
     int num_bands)
@@ -187,7 +174,7 @@
       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<float>(frame_length_, 0.f)),
       render_transfer_queue_(render_transfer_queue) {
@@ -196,25 +183,23 @@
 
 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<int>(input->num_bands()))
+  if (num_bands_ != static_cast<int>(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<void>(render_transfer_queue_->Insert(&render_queue_input_frame_));
 }
@@ -222,17 +207,14 @@
 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>(
               BlockProcessor::Create(AdjustConfig(config), sample_rate_hz))) {}
 EchoCanceller3::EchoCanceller3(const EchoCanceller3Config& config,
                                int sample_rate_hz,
-                               bool use_highpass_filter,
                                std::unique_ptr<BlockProcessor> block_processor)
     : data_dumper_(
           new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
@@ -259,24 +241,9 @@
                           config_.delay.fixed_capture_delay_samples) {
   RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
 
-  std::unique_ptr<CascadedBiQuadFilter> 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() = 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<int>(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<const float>(capture->channels()[k],
-                                                     capture->num_frames()));
+        DetectSaturation(rtc::ArrayView<const float>(
+            capture.channels_const()[k], capture.num_frames()));
     if (saturated_microphone_signal_) {
       break;
     }
@@ -336,10 +301,6 @@
 
   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 2782687..d7dea80 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 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<BlockProcessor> 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 @@
   // 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 @@
       RTC_GUARDED_BY(capture_race_checker_);
   std::vector<std::vector<float>> render_queue_output_frame_
       RTC_GUARDED_BY(capture_race_checker_);
-  std::unique_ptr<CascadedBiQuadFilter> capture_highpass_filter_
-      RTC_GUARDED_BY(capture_race_checker_);
   bool saturated_microphone_signal_ RTC_GUARDED_BY(capture_race_checker_) =
       false;
   std::vector<std::vector<float>> 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 1b6bdaf..a29b779 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 @@
   return true;
 }
 
+bool VerifyOutputFrameBitexactness(rtc::ArrayView<const float> reference,
+                                   rtc::ArrayView<const float> frame,
+                                   int offset) {
+  for (size_t k = 0; k < frame.size(); ++k) {
+    int reference_index = static_cast<int>(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 @@
   // output.
   void RunCaptureTransportVerificationTest() {
     EchoCanceller3 aec3(
-        EchoCanceller3Config(), sample_rate_hz_, false,
+        EchoCanceller3Config(), sample_rate_hz_,
         std::unique_ptr<BlockProcessor>(
             new CaptureTransportVerificationProcessor(num_bands_)));
 
@@ -191,10 +207,12 @@
   // block processor.
   void RunRenderTransportVerificationTest() {
     EchoCanceller3 aec3(
-        EchoCanceller3Config(), sample_rate_hz_, false,
+        EchoCanceller3Config(), sample_rate_hz_,
         std::unique_ptr<BlockProcessor>(
             new RenderTransportVerificationProcessor(num_bands_)));
 
+    std::vector<float> render_input;
+    std::vector<float> capture_output;
     for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
          ++frame_index) {
       aec3.AnalyzeCapture(&capture_buffer_);
@@ -204,12 +222,20 @@
       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 @@
         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 @@
       } 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 @@
       } 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 @@
   void RunRenderSwapQueueVerificationTest() {
     const EchoCanceller3Config config;
     EchoCanceller3 aec3(
-        config, sample_rate_hz_, false,
+        config, sample_rate_hz_,
         std::unique_ptr<BlockProcessor>(
             new RenderTransportVerificationProcessor(num_bands_)));
 
+    std::vector<float> render_input;
+    std::vector<float> capture_output;
+
     for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
          ++frame_index) {
       if (sample_rate_hz_ > 16000) {
@@ -482,6 +511,9 @@
         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 @@
                          &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 @@
         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 @@
     // 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 @@
     // 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 @@
     // 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 @@
     // 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 @@
   }
 }
 
-// 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 @@
 // 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 b6a41e2..2d136d8 100644
--- a/modules/audio_processing/audio_buffer.h
+++ b/modules/audio_processing/audio_buffer.h
@@ -32,6 +32,7 @@
 // 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 97babf9..bc61b52 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 @@
   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 @@
   // Accessed internally from capture or during initialization
   std::unique_ptr<AgcManagerDirect> agc_manager;
   std::unique_ptr<GainController2> gain_controller2;
-  std::unique_ptr<LowCutFilter> low_cut_filter;
+  std::unique_ptr<HighPassFilter> high_pass_filter;
   rtc::scoped_refptr<EchoDetector> echo_detector;
   std::unique_ptr<EchoCancellationImpl> echo_cancellation;
   std::unique_ptr<EchoControl> echo_controller;
@@ -547,7 +548,7 @@
     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 @@
   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 @@
     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::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 @@
           echo_control_factory_->Create(proc_sample_rate_hz());
     } else {
       private_submodules_->echo_controller = absl::make_unique<EchoCanceller3>(
-          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 1539cd5..6bda06a 100644
--- a/modules/audio_processing/audio_processing_impl.h
+++ b/modules/audio_processing/audio_processing_impl.h
@@ -193,7 +193,7 @@
     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 @@
       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 f6953ab..72bd673 100644
--- a/modules/audio_processing/audio_processing_impl_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_unittest.cc
@@ -239,13 +239,13 @@
 
   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 @@
   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 @@
     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 @@
 
   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 @@
       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 @@
       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 461236e..23657b8 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(
     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 @@
                       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 0000000..306bcbd
--- /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<float> channel_data = rtc::ArrayView<float>(
+        audio->split_bands(k)[0], audio->num_frames_per_band());
+    filters_[k]->Process(channel_data);
+  }
+}
+
+void HighPassFilter::Process(rtc::ArrayView<float> 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 0000000..b068206
--- /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 <memory>
+#include <vector>
+
+#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<float> audio);
+  void Reset();
+  void Reset(size_t num_channels);
+
+ private:
+  std::vector<std::unique_ptr<CascadedBiQuadFilter>> 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 0000000..4025454
--- /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 <vector>
+
+#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<float> ProcessOneFrame(const std::vector<float>& 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<float> 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<float>& input,
+                         const std::vector<float>& reference) {
+  const StreamConfig stream_config(16000, num_channels, false);
+  HighPassFilter high_pass_filter(num_channels);
+
+  std::vector<float> 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<float> 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<float> 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<float> CreateVector(const rtc::ArrayView<const float>& array_view) {
+  std::vector<float> 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<float> x_mono(160, 1.f);
+  std::vector<float> x_stereo(320, 1.f);
+  HighPassFilter lc(1);
+  std::vector<float> 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<const float>(kReferenceInput)),
+      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
+      CreateVector(rtc::ArrayView<const float>(kReference)));
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_processing/include/mock_audio_processing.h b/modules/audio_processing/include/mock_audio_processing.h
index 141a8ac..1c08726 100644
--- a/modules/audio_processing/include/mock_audio_processing.h
+++ b/modules/audio_processing/include/mock_audio_processing.h
@@ -13,6 +13,7 @@
 
 #include <memory>
 
+#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 307a7e8..0000000
--- 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 <stdint.h>
-
-#include <cstring>
-
-#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<int16_t>(tmp_int32 >> 13);
-
-      y[1] = static_cast<int16_t>((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<int32_t>(134217727), tmp_int32,
-                                 static_cast<int32_t>(-134217728));
-
-      // Convert back to Q0 and use rounding.
-      data[i] = static_cast<int16_t>(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<int16_t, AudioBuffer::kMaxSplitFrameLength> 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 86fbddd..0000000
--- 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 <memory>
-#include <vector>
-
-#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<std::unique_ptr<BiquadFilter>> 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 02c86e4..0000000
--- 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 <vector>
-
-#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<float> ProcessOneFrame(const std::vector<float>& 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<float> 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<float>& input,
-                         const std::vector<float>& reference) {
-  const StreamConfig stream_config(sample_rate, num_channels, false);
-  LowCutFilter low_cut_filter(num_channels, sample_rate);
-
-  std::vector<float> 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<float> 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<float> 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<float> CreateVector(const rtc::ArrayView<const float>& array_view) {
-  std::vector<float> 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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(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<const float>(kReferenceInput)),
-      CreateVector(rtc::ArrayView<const float>(kReference)));
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/utility/BUILD.gn b/modules/audio_processing/utility/BUILD.gn
index 0ba0f5b..80b2bde 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 @@
 }
 
 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 5dfd7c5..08b9464 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 <algorithm>
 
@@ -53,10 +53,14 @@
   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<CascadedBiQuadFilter::BiQuadParam>& biquad_params) {
@@ -85,6 +89,12 @@
   }
 }
 
+void CascadedBiQuadFilter::Reset() {
+  for (auto& biquad : biquads_) {
+    biquad.Reset();
+  }
+}
+
 void CascadedBiQuadFilter::ApplyBiQuad(rtc::ArrayView<const float> x,
                                        rtc::ArrayView<float> 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 34085f1..120b52a 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 <stddef.h>
 
@@ -17,7 +17,6 @@
 #include <vector>
 
 #include "api/array_view.h"
-#include "rtc_base/constructor_magic.h"
 
 namespace webrtc {
 
@@ -30,7 +29,7 @@
                 std::complex<float> pole,
                 float gain,
                 bool mirror_zero_along_i_axis = false);
-    BiQuadParam(const BiQuadParam&);
+    explicit BiQuadParam(const BiQuadParam&);
     std::complex<float> zero;
     std::complex<float> pole;
     float gain;
@@ -43,9 +42,10 @@
   };
 
   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 @@
   CascadedBiQuadFilter(
       const CascadedBiQuadFilter::BiQuadCoefficients& coefficients,
       size_t num_biquads);
-  CascadedBiQuadFilter(
+  explicit CascadedBiQuadFilter(
       const std::vector<CascadedBiQuadFilter::BiQuadParam>& 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<const float> x, rtc::ArrayView<float> y);
   // Applies the biquads on the values in y in an in-place manner.
   void Process(rtc::ArrayView<float> y);
+  // Resets the filter to its initial state.
+  void Reset();
 
  private:
   void ApplyBiQuad(rtc::ArrayView<const float> x,
@@ -68,10 +73,8 @@
                    CascadedBiQuadFilter::BiQuad* biquad);
 
   std::vector<BiQuad> 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 57f4b04..88a31ba 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 @@
   }
 }
 
+// Verifies that the reset functionality works as intended.
+TEST(CascadedBiquadFilter, HighPassConfiguration) {
+  CascadedBiQuadFilter filter(kHighPassFilterCoefficients, 2);
+
+  std::vector<float> values1(100, 1.f);
+  filter.Process(values1);
+
+  filter.Reset();
+
+  std::vector<float> 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.