[mixer_service] Move filters to lib/processing

This change also removes unused point filter.

Bug: 87651

Multiply: audio-libprocessing-unittests
Multiply: audio_core_unittests
Multiply: audio_mixer_unittests
Multiply: audio-core-api-pipeline-tests
Multiply: audio-core-fidelity-test
Multiply: audio_fidelity_tests
Change-Id: Ia2020f6a63e9ae08e7f5bf3c7e0b1df2d02dd155
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/693305
Reviewed-by: Tom Bergan <tombergan@google.com>
Commit-Queue: Alper Gungormusler <alperg@google.com>
diff --git a/src/media/audio/audio_core/BUILD.gn b/src/media/audio/audio_core/BUILD.gn
index 45d7499..a0657b2 100644
--- a/src/media/audio/audio_core/BUILD.gn
+++ b/src/media/audio/audio_core/BUILD.gn
@@ -248,7 +248,7 @@
   output_name = "audio_core"
   deps = [
     ":audio_core_main",
-    "//src/media/audio/audio_core/mixer:empty_coefficient_tables",
+    "//src/media/audio/lib/processing:empty_coefficient_tables",
   ]
 }
 
@@ -256,7 +256,7 @@
   output_name = "audio_core_with_prebuilt_coefficient_tables"
   deps = [
     ":audio_core_main",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
   ]
 }
 
@@ -333,13 +333,13 @@
     "//src/lib/storage/vfs/cpp",
     "//src/lib/testing/loop_fixture",
     "//src/media/audio/audio_core/mixer",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
     "//src/media/audio/effects/test_effects:test_effects_v2",
     "//src/media/audio/lib/clock/testing",
     "//src/media/audio/lib/effects_loader",
     "//src/media/audio/lib/effects_loader/testing",
     "//src/media/audio/lib/format",
     "//src/media/audio/lib/processing",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//third_party/googletest:gmock",
     "//zircon/system/ulib/async-loop:async-loop-cpp",
     "//zircon/system/ulib/async-loop:async-loop-default",
@@ -373,7 +373,7 @@
   sources = [ "policy_loader_fuzzer.cc" ]
   deps = [
     ":audio_core_lib",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
   ]
 }
 
diff --git a/src/media/audio/audio_core/mixer/BUILD.gn b/src/media/audio/audio_core/mixer/BUILD.gn
index 72cb626..c0f5b57 100644
--- a/src/media/audio/audio_core/mixer/BUILD.gn
+++ b/src/media/audio/audio_core/mixer/BUILD.gn
@@ -9,25 +9,9 @@
   public_deps = [ "//src/media/audio/lib/format:constants" ]
 }
 
-source_set("coefficient_table") {
-  sources = [
-    "coefficient_table.cc",
-    "coefficient_table.h",
-  ]
-
-  public_deps = [
-    ":constants",
-    "//sdk/lib/stdcompat",
-    "//sdk/lib/syslog/cpp",
-  ]
-}
-
 source_set("mixer") {
   sources = [
     "channel_strip.h",
-    "coefficient_table_cache.h",
-    "filter.cc",
-    "filter.h",
     "gain.cc",
     "gain.h",
     "intersect.cc",
@@ -47,7 +31,6 @@
   ]
 
   public_deps = [
-    ":coefficient_table",
     ":constants",
     "//sdk/fidl/fuchsia.media",
     "//zircon/system/ulib/fbl",
@@ -86,25 +69,6 @@
   deps = [ "tools" ]
 }
 
-# Any executable which uses :mixer (either directly or transitively) must also
-# include either prebuilt or empty coefficient tables, via one of the following
-# two build rules. The decision of which tables to include is usually left to
-# the top-most build rule (i.e., the executable), since that rule often has the
-# most insight into system constraints, such as code size.
-
-source_set("prebuilt_coefficient_tables") {
-  sources = [ "$target_gen_dir/coefficient_table_data_prebuilt.cc" ]
-  deps = [
-    ":build_coefficient_table_data_prebuilt_cc",
-    ":coefficient_table",
-  ]
-}
-
-source_set("empty_coefficient_tables") {
-  sources = [ "coefficient_table_data_empty.cc" ]
-  deps = [ ":coefficient_table" ]
-}
-
 group("tests") {
   testonly = true
   deps = [
@@ -121,9 +85,6 @@
   sources = [
     "bookkeeping_unittest.cc",
     "channel_strip_unittest.cc",
-    "coefficient_table_cache_unittest.cc",
-    "coefficient_table_unittest.cc",
-    "filter_unittest.cc",
     "gain_unittest.cc",
     "intersect_unittest.cc",
     "no_op_unittest.cc",
@@ -137,10 +98,10 @@
   deps = [
     ":mixer",
     "//src/lib/fxl/test:gtest_main",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
     "//src/media/audio/lib/format",
     "//src/media/audio/lib/format2",
     "//src/media/audio/lib/processing",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//src/media/audio/lib/test:constants",
     "//third_party/googletest:gmock",
     "//zircon/system/ulib/fbl",
@@ -162,7 +123,7 @@
     "//sdk/lib/syslog/cpp",
     "//src/lib/fxl/test:gtest_main",
     "//src/lib/testing/loop_fixture",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//third_party/googletest:gmock",
   ]
 }
@@ -176,27 +137,3 @@
     }
   }
 }
-
-# This executable is run automatically as part of the build deps for
-# :prebuilt_coefficient_tables. It can be run manually -- the binary
-# can be found adjacent to other host tools.
-executable("gen_audio_filter_coefficient_tables") {
-  sources = [
-    "coefficient_table.cc",
-    "coefficient_table.h",
-    "constants.h",
-    "gen_coefficient_tables.cc",
-  ]
-  deps = [
-    "//sdk/lib/stdcompat",
-    "//src/media/audio/lib/format:constants",
-  ]
-  defines = [ "BUILDING_FUCHSIA_AUDIO_HOST_TOOL=1" ]
-}
-
-compiled_action("build_coefficient_table_data_prebuilt_cc") {
-  tool = ":gen_audio_filter_coefficient_tables"
-  outputs = [ "$target_gen_dir/coefficient_table_data_prebuilt.cc" ]
-  args = [ rebase_path(target_gen_dir, root_build_dir) +
-           "/coefficient_table_data_prebuilt.cc" ]
-}
diff --git a/src/media/audio/audio_core/mixer/coefficient_table_data_empty.cc b/src/media/audio/audio_core/mixer/coefficient_table_data_empty.cc
deleted file mode 100644
index f77eadd..0000000
--- a/src/media/audio/audio_core/mixer/coefficient_table_data_empty.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2020 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
-
-namespace media::audio::mixer {
-
-// This file is linked by builds that have no prebuilt coefficient tables.
-const cpp20::span<const PrebuiltSincFilterCoefficientTable> kPrebuiltSincFilterCoefficientTables;
-
-}  // namespace media::audio::mixer
diff --git a/src/media/audio/audio_core/mixer/sinc_sampler.cc b/src/media/audio/audio_core/mixer/sinc_sampler.cc
index 541e39b1..840871f 100644
--- a/src/media/audio/audio_core/mixer/sinc_sampler.cc
+++ b/src/media/audio/audio_core/mixer/sinc_sampler.cc
@@ -11,12 +11,14 @@
 
 #include "src/media/audio/audio_core/mixer/channel_strip.h"
 #include "src/media/audio/audio_core/mixer/constants.h"
-#include "src/media/audio/audio_core/mixer/filter.h"
 #include "src/media/audio/audio_core/mixer/position_manager.h"
+#include "src/media/audio/lib/processing/filter.h"
 #include "src/media/audio/lib/processing/sampler.h"
 
 namespace media::audio::mixer {
 
+using ::media_audio::SincFilter;
+
 template <int32_t DestChanCount, typename SourceSampleType, int32_t SourceChanCount>
 class SincSamplerImpl : public SincSampler {
  public:
diff --git a/src/media/audio/audio_core/mixer/sinc_sampler_unittest.cc b/src/media/audio/audio_core/mixer/sinc_sampler_unittest.cc
index 1077cc7..adbe995 100644
--- a/src/media/audio/audio_core/mixer/sinc_sampler_unittest.cc
+++ b/src/media/audio/audio_core/mixer/sinc_sampler_unittest.cc
@@ -10,8 +10,8 @@
 #include <fbl/algorithm.h>
 #include <gtest/gtest.h>
 
-#include "src/media/audio/audio_core/mixer/filter.h"
 #include "src/media/audio/lib/format/constants.h"
+#include "src/media/audio/lib/processing/filter.h"
 #include "src/media/audio/lib/processing/gain.h"
 
 namespace media::audio::mixer {
@@ -433,8 +433,8 @@
   auto mixer = SelectSincSampler(1, 1, 48000, 48000, fuchsia::media::AudioSampleFormat::FLOAT);
   ASSERT_NE(mixer, nullptr);
 
-  EXPECT_EQ(mixer->pos_filter_width().raw_value(), SincFilter::kFracSideLength - 1);
-  EXPECT_EQ(mixer->neg_filter_width().raw_value(), SincFilter::kFracSideLength - 1);
+  EXPECT_EQ(mixer->pos_filter_width().raw_value(), media_audio::SincFilter::kFracSideLength - 1);
+  EXPECT_EQ(mixer->neg_filter_width().raw_value(), media_audio::SincFilter::kFracSideLength - 1);
 }
 
 // Test basic position advancing, for integer rate and same-sized source and dest buffers.
diff --git a/src/media/audio/audio_core/mixer/test/BUILD.gn b/src/media/audio/audio_core/mixer/test/BUILD.gn
index d9e8b4f..d31b1b8 100644
--- a/src/media/audio/audio_core/mixer/test/BUILD.gn
+++ b/src/media/audio/audio_core/mixer/test/BUILD.gn
@@ -42,10 +42,10 @@
     "//src/lib/fxl/test:test_settings",
     "//src/lib/testing/loop_fixture",
     "//src/media/audio/audio_core/mixer",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
     "//src/media/audio/lib/analysis",
     "//src/media/audio/lib/format",
     "//src/media/audio/lib/processing",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//third_party/googletest:gmock",
     "//zircon/system/ulib/fbl",
   ]
diff --git a/src/media/audio/audio_core/mixer/tools/BUILD.gn b/src/media/audio/audio_core/mixer/tools/BUILD.gn
index 67fefdf..99a933c 100644
--- a/src/media/audio/audio_core/mixer/tools/BUILD.gn
+++ b/src/media/audio/audio_core/mixer/tools/BUILD.gn
@@ -22,11 +22,11 @@
   deps = [
     "//src/lib/fxl",
     "//src/media/audio/audio_core/mixer",
-    "//src/media/audio/audio_core/mixer:empty_coefficient_tables",
     "//src/media/audio/audio_core/mixer/test:frequency_set",
     "//src/media/audio/lib/analysis",
     "//src/media/audio/lib/format",
     "//src/media/audio/lib/processing",
+    "//src/media/audio/lib/processing:empty_coefficient_tables",
     "//src/performance/lib/profiler",
     "//zircon/system/ulib/perftest",
   ]
diff --git a/src/media/audio/audio_core/test/api/BUILD.gn b/src/media/audio/audio_core/test/api/BUILD.gn
index 0544649..36ea335 100644
--- a/src/media/audio/audio_core/test/api/BUILD.gn
+++ b/src/media/audio/audio_core/test/api/BUILD.gn
@@ -86,16 +86,16 @@
   source = "audio_core_fidelity_test.cc"
   executable_deps = [
     ":fidelity_results",
-    "//src/media/audio/audio_core/mixer:coefficient_table",
     "//src/media/audio/lib/analysis",
+    "//src/media/audio/lib/processing:coefficient_table",
   ]
 }
 
 audio_core_api_test_component("audio_core_thermal_test") {
   source = "audio_core_thermal_test.cc"
   executable_deps = [
-    "//src/media/audio/audio_core/mixer:coefficient_table",
     "//src/media/audio/lib/analysis",
+    "//src/media/audio/lib/processing:coefficient_table",
   ]
 }
 
diff --git a/src/media/audio/audio_core/test/api/audio_core_fidelity_test.cc b/src/media/audio/audio_core/test/api/audio_core_fidelity_test.cc
index 01f1891..f9db2a8 100644
--- a/src/media/audio/audio_core/test/api/audio_core_fidelity_test.cc
+++ b/src/media/audio/audio_core/test/api/audio_core_fidelity_test.cc
@@ -9,11 +9,11 @@
 
 #include "fuchsia/media/audio/cpp/fidl.h"
 #include "src/media/audio/audio_core/driver_output.h"
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
 #include "src/media/audio/audio_core/test/api/fidelity_results.h"
 #include "src/media/audio/audio_core/testing/integration/hermetic_fidelity_test.h"
 #include "src/media/audio/audio_core/threading_model.h"
 #include "src/media/audio/lib/analysis/generators.h"
+#include "src/media/audio/lib/processing/coefficient_table.h"
 
 using ASF = fuchsia::media::AudioSampleFormat;
 
@@ -39,7 +39,7 @@
       AUDIO_STREAM_UNIQUE_ID_BUILTIN_SPEAKERS;
 
   static constexpr size_t kFilterWidthFrames =
-      mixer::SincFilterCoefficientTable::kMaxFracSideLength >> Fixed::Format::FractionalBits;
+      media_audio::SincFilterCoefficientTable::kMaxFracSideLength >> Fixed::Format::FractionalBits;
 
   static HermeticPipelineTest::PipelineConstants pipeline_constants(int32_t source_rate,
                                                                     int32_t num_mix_stages = 1) {
diff --git a/src/media/audio/audio_core/test/api/fuzzer/BUILD.gn b/src/media/audio/audio_core/test/api/fuzzer/BUILD.gn
index 5e584a4..72463a4 100644
--- a/src/media/audio/audio_core/test/api/fuzzer/BUILD.gn
+++ b/src/media/audio/audio_core/test/api/fuzzer/BUILD.gn
@@ -15,9 +15,9 @@
     "//sdk/lib/media/audio/cpp",
     "//src/media/audio/audio_core:audio-core-for-test_audio_core_nodevfs_component",
     "//src/media/audio/audio_core:audio_core_lib",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
     "//src/media/audio/audio_core/testing",
     "//src/media/audio/lib/audio_test_devmgr:audio-test-devmgr",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//src/media/audio/lib/test:hermetic_audio_test",
   ]
   services = [
diff --git a/src/media/audio/audio_core/test/config_validator/BUILD.gn b/src/media/audio/audio_core/test/config_validator/BUILD.gn
index 32be814..e6c137b 100644
--- a/src/media/audio/audio_core/test/config_validator/BUILD.gn
+++ b/src/media/audio/audio_core/test/config_validator/BUILD.gn
@@ -9,6 +9,6 @@
     "//src/lib/files",
     "//src/lib/fxl/test:gtest_main",
     "//src/media/audio/audio_core:audio_core_lib",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
   ]
 }
diff --git a/src/media/audio/audio_core/testing/integration/BUILD.gn b/src/media/audio/audio_core/testing/integration/BUILD.gn
index a70522f..98e31c7 100644
--- a/src/media/audio/audio_core/testing/integration/BUILD.gn
+++ b/src/media/audio/audio_core/testing/integration/BUILD.gn
@@ -30,12 +30,12 @@
     "//sdk/lib/sys/inspect/cpp",
     "//sdk/lib/syslog/cpp",
     "//src/media/audio/audio_core:audio_core_lib",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
     "//src/media/audio/effects/test_effects:test_effects_v2",
     "//src/media/audio/lib/analysis",
     "//src/media/audio/lib/clock",
     "//src/media/audio/lib/format",
     "//src/media/audio/lib/processing",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//src/media/audio/lib/test:comparators",
     "//src/media/audio/lib/test:constants",
     "//src/media/audio/lib/test:test_fixture",
diff --git a/src/media/audio/audio_core/tools/output_pipeline_benchmark/pipeline_benchmark.gni b/src/media/audio/audio_core/tools/output_pipeline_benchmark/pipeline_benchmark.gni
index d1cc6d6..1a29c97 100644
--- a/src/media/audio/audio_core/tools/output_pipeline_benchmark/pipeline_benchmark.gni
+++ b/src/media/audio/audio_core/tools/output_pipeline_benchmark/pipeline_benchmark.gni
@@ -79,12 +79,12 @@
       "//sdk/fidl/fuchsia.media",
       "//src/lib/fxl",
       "//src/media/audio/audio_core:audio_core_lib",
-      "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
       "//src/media/audio/audio_core/testing",
       "//src/media/audio/lib/analysis",
       "//src/media/audio/lib/clock/testing",
       "//src/media/audio/lib/effects_loader",
       "//src/media/audio/lib/format",
+      "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
       "//src/performance/lib/profiler",
       "//zircon/system/ulib/perftest",
     ]
diff --git a/src/media/audio/lib/clock/testing/BUILD.gn b/src/media/audio/lib/clock/testing/BUILD.gn
index 7d4a5fb..a1db839 100644
--- a/src/media/audio/lib/clock/testing/BUILD.gn
+++ b/src/media/audio/lib/clock/testing/BUILD.gn
@@ -37,7 +37,7 @@
     "//src/lib/fxl/test:gtest_main",
     "//src/lib/testing/loop_fixture",
     "//src/media/audio/audio_core:audio_core_lib",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
   ]
 }
 
diff --git a/src/media/audio/lib/processing/BUILD.gn b/src/media/audio/lib/processing/BUILD.gn
index f9505f5..9070960 100644
--- a/src/media/audio/lib/processing/BUILD.gn
+++ b/src/media/audio/lib/processing/BUILD.gn
@@ -9,6 +9,19 @@
   deps = [ ":audio-libprocessing-unittests" ]
 }
 
+source_set("coefficient_table") {
+  sources = [
+    "coefficient_table.cc",
+    "coefficient_table.h",
+  ]
+
+  public_deps = [
+    "//sdk/lib/stdcompat",
+    "//sdk/lib/syslog/cpp",
+    "//src/media/audio/lib/format2:fixed",
+  ]
+}
+
 source_set("processing") {
   sources = [
     "gain_control.cc",
@@ -25,6 +38,9 @@
 
 source_set("sampler") {
   sources = [
+    "coefficient_table_cache.h",
+    "filter.cc",
+    "filter.h",
     "gain.h",
     "point_sampler.cc",
     "point_sampler.h",
@@ -32,8 +48,10 @@
   ]
 
   deps = [
+    ":coefficient_table",
     "//sdk/lib/syslog/cpp",
     "//src/media/audio/lib/format2",
+    "//zircon/system/ulib/trace",
   ]
 
   # Building without optimizations causes significant slowdowns for these components; the additional
@@ -53,12 +71,54 @@
   ]
 }
 
+# Any executable which uses `sampler` (either directly or transitively) must also include either
+# `prebuilt_coefficient_tables` or `empty_coefficient_tables` below. The decision of which tables to
+# include is usually left to the top-most build rule (i.e., the executable), since that rule often
+# has the most insight into system constraints, such as code size.
+source_set("prebuilt_coefficient_tables") {
+  sources = [ "$target_gen_dir/coefficient_table_data_prebuilt.cc" ]
+  deps = [
+    ":build_coefficient_table_data_prebuilt_cc",
+    ":coefficient_table",
+  ]
+}
+
+source_set("empty_coefficient_tables") {
+  sources = [ "coefficient_table_data_empty.cc" ]
+  deps = [ ":coefficient_table" ]
+}
+
+# This executable is run automatically as part of the build deps for `prebuilt_coefficient_tables`.
+# It can also be run manually - the binary can be found adjacent to other host tools.
+executable("gen_audio_filter_coefficient_tables") {
+  sources = [
+    "coefficient_table.cc",
+    "coefficient_table.h",
+    "gen_coefficient_tables.cc",
+  ]
+  deps = [
+    "//sdk/lib/stdcompat",
+    "//src/media/audio/lib/format2:fixed",
+  ]
+  defines = [ "BUILDING_FUCHSIA_AUDIO_HOST_TOOL=1" ]
+}
+
+compiled_action("build_coefficient_table_data_prebuilt_cc") {
+  tool = ":gen_audio_filter_coefficient_tables"
+  outputs = [ "$target_gen_dir/coefficient_table_data_prebuilt.cc" ]
+  args = [ rebase_path(target_gen_dir, root_build_dir) +
+           "/coefficient_table_data_prebuilt.cc" ]
+}
+
 executable("unittest-bin") {
   visibility = [ ":*" ]
   testonly = true
   output_name = "audio-libprocessing-unittests"
 
   sources = [
+    "coefficient_table_cache_unittest.cc",
+    "coefficient_table_unittest.cc",
+    "filter_unittest.cc",
     "gain_control_unittest.cc",
     "gain_unittest.cc",
     "point_sampler_unittest.cc",
@@ -66,9 +126,12 @@
   ]
 
   deps = [
+    ":coefficient_table",
     ":processing",
+    "//sdk/lib/syslog/cpp",
     "//src/lib/fxl/test:gtest_main",
     "//src/media/audio/lib/format2",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//third_party/googletest:gmock",
   ]
 }
diff --git a/src/media/audio/audio_core/mixer/coefficient_table.cc b/src/media/audio/lib/processing/coefficient_table.cc
similarity index 70%
rename from src/media/audio/audio_core/mixer/coefficient_table.cc
rename to src/media/audio/lib/processing/coefficient_table.cc
index 0a9393d..7cd09a3 100644
--- a/src/media/audio/audio_core/mixer/coefficient_table.cc
+++ b/src/media/audio/lib/processing/coefficient_table.cc
@@ -1,33 +1,15 @@
-// Copyright 2020 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
+#include "src/media/audio/lib/processing/coefficient_table.h"
 
 #include <algorithm>
+#include <limits>
+#include <memory>
 
-namespace media::audio::mixer {
+namespace media_audio {
 
-// Calculate our nearest-neighbor filter. With it we perform frame-rate conversion.
-std::unique_ptr<CoefficientTable> PointFilterCoefficientTable::Create(Inputs inputs) {
-  CoefficientTableBuilder table(inputs.side_length, inputs.num_frac_bits);
-
-  // kHalfFrameIdx should always be the last idx in the filter table, because our ctor sets
-  // side_length to (1 << (num_frac_bits - 1)), which == (frac_size >> 1)
-  const int64_t kHalfFrameIdx = 1 << (inputs.num_frac_bits - 1);  // frac_half
-  FX_CHECK(inputs.side_length == kHalfFrameIdx + 1);
-
-  // Just a rectangular window, with the exact midpoint performing averaging (for zero phase).
-  for (auto idx = 0; idx < kHalfFrameIdx; ++idx) {
-    table[idx] = 1.0f;
-  }
-
-  // Here we average, so that we are zero-phase
-  table[kHalfFrameIdx] = 0.5f;
-
-  return table.Build();
-}
-
-// Calculate our linear-interpolation filter. With it we perform frame-rate conversion.
 std::unique_ptr<CoefficientTable> LinearFilterCoefficientTable::Create(Inputs inputs) {
   CoefficientTableBuilder table(inputs.side_length, inputs.num_frac_bits);
 
@@ -51,7 +33,6 @@
   return table.Build();
 }
 
-// Calculate our windowed-sinc FIR filter. With it we perform band-limited frame-rate conversion.
 std::unique_ptr<CoefficientTable> SincFilterCoefficientTable::Create(Inputs inputs) {
   CoefficientTableBuilder table(inputs.side_length, inputs.num_frac_bits);
 
@@ -102,4 +83,4 @@
   return table.Build();
 }
 
-}  // namespace media::audio::mixer
+}  // namespace media_audio
diff --git a/src/media/audio/audio_core/mixer/coefficient_table.h b/src/media/audio/lib/processing/coefficient_table.h
similarity index 66%
rename from src/media/audio/audio_core/mixer/coefficient_table.h
rename to src/media/audio/lib/processing/coefficient_table.h
index 1699a51..d9ab300 100644
--- a/src/media/audio/audio_core/mixer/coefficient_table.h
+++ b/src/media/audio/lib/processing/coefficient_table.h
@@ -1,22 +1,23 @@
-// Copyright 2020 The Fuchsia Authors. All rights reserved.
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_COEFFICIENT_TABLE_H_
-#define SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_COEFFICIENT_TABLE_H_
+#ifndef SRC_MEDIA_AUDIO_LIB_PROCESSING_COEFFICIENT_TABLE_H_
+#define SRC_MEDIA_AUDIO_LIB_PROCESSING_COEFFICIENT_TABLE_H_
 
 #include <lib/stdcompat/span.h>
 
+#include <algorithm>
 #include <cmath>
-#include <map>
 #include <memory>
-#include <mutex>
+#include <optional>
+#include <tuple>
+#include <utility>
 #include <vector>
 
-#include "src/media/audio/audio_core/mixer/constants.h"
-#include "src/media/audio/lib/format/constants.h"
+#include "src/media/audio/lib/format2/fixed.h"
 
-// coefficient_table.h is included by gen_coefficient_tables.cc, which does not have access to
+// `coefficient_table.h` is included by `gen_coefficient_tables.cc`, which does not have access to
 // Fuchsia headers because it is compiled as a host binary.
 #ifndef BUILDING_FUCHSIA_AUDIO_HOST_TOOL
 #include <lib/syslog/cpp/macros.h>  // nogncheck
@@ -25,22 +26,22 @@
 #define FX_CHECK(cond) assert(cond)
 #endif
 
-namespace media::audio::mixer {
+namespace media_audio {
 
-// CoefficientTable is a shim around std::vector that maps indicies into a physical addressing
-// scheme that is most optimal WRT to how this table is typically accessed. Specifically accesses
-// are most commonly with an integral stride (that is 1 << frac_bits stride). Optimize for this use
-// case by placing these values physically contiguously in memory.
+// `CoefficientTable` is a shim around `std::vector` that maps indices into a physical addressing
+// scheme that is most optimal with respect to how this table is typically accessed. More
+// specifically, they are most commonly accessed with an integral stride (that is `1 << frac_bits`
+// stride). We optimize for this use case by placing these values physically contiguously in memory.
 //
 // Coefficient tables represent one side of a symmetric convolution filter. Coefficients cover the
-// entire discrete space of fractional position values, but for any calculation we reference only
-// a small subset of these values (see ReadSlice for an example).
+// entire discrete space of fractional position values, but for any calculation we reference only a
+// small subset of these values (see `ReadSlice` below for an example).
 class CoefficientTable {
  public:
-  // |width| is the filter width of this table, in fixed point format with |frac_bits| of fractional
-  // precision. The |width| will determine the number of entries in the table, which will be |width|
-  // rounded up to the nearest integer in the same fixed-point format. |data| provides the raw table
-  // data ordered by physical address. If |data| is empty, storage is allocated automatically.
+  // `width` is the filter width of this table, in fixed point format with `frac_bits` of fractional
+  // precision. The `width` will determine the number of entries in the table, which will be `width`
+  // rounded up to the nearest integer in the same fixed-point format. `data` provides the raw table
+  // data ordered by physical address. If `data` is empty, storage is allocated automatically.
   CoefficientTable(int64_t width, int32_t frac_bits, cpp20::span<const float> data)
       : stride_(ComputeStride(width, frac_bits)),
         frac_filter_width_(width),
@@ -48,22 +49,24 @@
         frac_mask_((1 << frac_bits_) - 1),
         storage_(data.empty() ? std::make_optional<std::vector<float>>(stride_ * (1 << frac_bits))
                               : std::nullopt),
-        table_(data.empty() ? cpp20::span<const float>(&(*storage_)[0], storage_->size()) : data) {
+        table_(data.empty() ? cpp20::span<const float>(storage_->begin(), storage_->end()) : data) {
     FX_CHECK(frac_filter_width_ >= 0);
     FX_CHECK(static_cast<int64_t>(table_.size()) == stride_ * (1 << frac_bits));
   }
 
   const float& operator[](int64_t offset) const { return table_[PhysicalIndex(offset)]; }
 
-  // Reads |num_coefficients| coefficients starting at |offset|. The result is a pointer to
-  // |num_coefficients| coefficients with the following semantics:
+  // Reads `num_coefficients` coefficients starting at `offset`. The result is a pointer to
+  // `num_coefficients` coefficients with the following semantics:
   //
+  // ```
   // auto c = new CoefficientTable(width, frac_bits);
   // auto f = c->ReadSlice(offset, size);
   // ASSERT_EQ(f[0], c[off + 0 << frac_bits]);
   // ASSERT_EQ(f[1], c[off + 1 << frac_bits]);
   //  ...
   // ASSERT_EQ(f[size], c[off + size << frac_bits]);
+  // ```
   const float* ReadSlice(int64_t offset, int64_t num_coefficients) const {
     if (num_coefficients <= 0 ||
         offset + ((num_coefficients - 1) << frac_bits_) > frac_filter_width_) {
@@ -103,8 +106,8 @@
   cpp20::span<const float> table_;
 };
 
-// CoefficientTableBuilder constructs a single CoefficientTable.
-// Once constructed, the CoefficientTable is immutable.
+// `CoefficientTableBuilder` constructs a single `CoefficientTable`.
+// Once constructed, the `CoefficientTable` is immutable.
 class CoefficientTableBuilder {
  public:
   CoefficientTableBuilder(int64_t width, int32_t frac_bits)
@@ -122,34 +125,10 @@
   std::unique_ptr<CoefficientTable> table_;
 };
 
-// Nearest-neighbor "zero-order interpolation" resampler, implemented using the convolution
-// filter. Length on both sides is half a frame + 1 subframe (expressed in our fixed-point
-// fractional scale), modulo the stretching effects of downsampling.
-//
-// Example: for frac_size 1000, filter_length would be 500, entailing coefficient values for
-// locations from that exact position, up to positions as much as 500 away. This means:
-// - Fractional source pos 1.499 requires frames between 0.999 and 1.999, thus source frame 1
-// - Fractional source pos 1.500 requires frames between 1.000 and 2.000, thus source frames 1 and 2
-// - Fractional source pos 1.501 requires frames between 1.001 and 2.001, thus source frame 2
-// For source pos .5, we average the pre- and post- values so as to achieve zero phase delay
-class PointFilterCoefficientTable {
- public:
-  struct Inputs {
-    int64_t side_length;
-    int32_t num_frac_bits;
-
-    bool operator<(const Inputs& rhs) const {
-      return std::tie(side_length, num_frac_bits) < std::tie(rhs.side_length, rhs.num_frac_bits);
-    }
-  };
-
-  static std::unique_ptr<CoefficientTable> Create(Inputs);
-};
-
 // Linear interpolation, implemented using the convolution filter.
 // Length on both sides is one frame, modulo the stretching effects of downsampling.
 //
-// Example: for frac_size 1000, filter_length would be 999, entailing coefficient values for
+// Example: for `frac_size` 1000, `filter_length` would be 999, entailing coefficient values for
 // locations from that exact position, up to positions as much as 999 away. This means:
 // -Fractional source pos 1.999 requires frames between 1.000 and 2.998, thus source frames 1 and 2
 // -Fractional source pos 2.001 requires frames between 1.002 and 3.000, thus source frames 2 and 3
@@ -166,6 +145,7 @@
     }
   };
 
+  // Creates linear-interpolation filter with frame-rate conversion.
   static std::unique_ptr<CoefficientTable> Create(Inputs);
 };
 
@@ -201,8 +181,8 @@
           static_cast<int64_t>(std::ceil(static_cast<double>(filter_length * source_frame_rate) /
                                          static_cast<double>(dest_frame_rate)));
 
-      // For down-sampling ratios beyond kMaxDownsampleRatioForFullSideTaps the effective number of
-      // side taps decreases proportionally -- rate-conversion quality gracefully degrades.
+      // For down-sampling ratios beyond `kMaxDownsampleRatioForFullSideTaps` the effective number
+      // of side taps decreases proportionally -- rate-conversion quality gracefully degrades.
       filter_length = std::min(filter_length, kMaxFracSideLength);
     }
 
@@ -217,10 +197,11 @@
     };
   }
 
+  // Creates windowed-sinc FIR filter with band-limited frame-rate conversion.
   static std::unique_ptr<CoefficientTable> Create(Inputs);
 };
 
-// These global structs This global struct describes a set of prebuilt coefficient tables.
+// This global struct describes a set of prebuilt coefficient tables.
 struct PrebuiltSincFilterCoefficientTable {
   int32_t source_rate;
   int32_t dest_rate;
@@ -228,11 +209,10 @@
 };
 
 // The list of prebuilt coefficient tables.
-// This uses std::array so it can directly reference data in .rodata without reallocating
-// (std::vector would allocate and copy from .rodata).
+// This uses `std::array` so it can directly reference data in `.rodata` without reallocating.
 extern const cpp20::span<const PrebuiltSincFilterCoefficientTable>
     kPrebuiltSincFilterCoefficientTables;
 
-}  // namespace media::audio::mixer
+}  // namespace media_audio
 
-#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_COEFFICIENT_TABLE_H_
+#endif  // SRC_MEDIA_AUDIO_LIB_PROCESSING_COEFFICIENT_TABLE_H_
diff --git a/src/media/audio/audio_core/mixer/coefficient_table_cache.h b/src/media/audio/lib/processing/coefficient_table_cache.h
similarity index 74%
rename from src/media/audio/audio_core/mixer/coefficient_table_cache.h
rename to src/media/audio/lib/processing/coefficient_table_cache.h
index d8a7c28..4f80023 100644
--- a/src/media/audio/audio_core/mixer/coefficient_table_cache.h
+++ b/src/media/audio/lib/processing/coefficient_table_cache.h
@@ -1,34 +1,34 @@
-// Copyright 2020 The Fuchsia Authors. All rights reserved.
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_COEFFICIENT_TABLE_CACHE_H_
-#define SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_COEFFICIENT_TABLE_CACHE_H_
+#ifndef SRC_MEDIA_AUDIO_LIB_PROCESSING_COEFFICIENT_TABLE_CACHE_H_
+#define SRC_MEDIA_AUDIO_LIB_PROCESSING_COEFFICIENT_TABLE_CACHE_H_
 
 #include <lib/fit/function.h>
 #include <lib/syslog/cpp/macros.h>
-#include <zircon/compiler.h>
 
 #include <map>
 #include <memory>
 #include <mutex>
+#include <utility>
 
 #include "src/lib/fxl/synchronization/thread_annotations.h"
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
+#include "src/media/audio/lib/processing/coefficient_table.h"
 
-namespace media::audio::mixer {
+namespace media_audio {
 
-// A cache of CoefficientTables. These use a lot of memory so we try to reuse them as much as
-// possible. For example, different Filters might use the same underlying coefficient table with
-// slightly different Filter parameters. Additionally, different mixers might use the same Filter.
+// A cache of `CoefficientTables`. These use a lot of memory so we try to reuse them as much as
+// possible. For example, different filters might use the same underlying coefficient table with
+// slightly different filter parameters. Additionally, different samplers might use the same filter.
 //
-// InputT defines the set of inputs that are used to construct the CoefficientTable.
+// `InputT` defines the set of inputs that are used to construct the CoefficientTable.
 template <class InputT>
 class CoefficientTableCache {
  public:
-  // Thread-safe reference-counted pointer to a cached CoefficientTable.
-  // This is like a std::shared_ptr, except the destructor runs atomically with Get()
-  // to simplify cache garbage collection.
+  // Thread-safe reference-counted pointer to a cached `CoefficientTable`.
+  // This is like a `std::shared_ptr`, except the destructor runs atomically with a `Get` call to
+  // simplify cache garbage collection.
   class SharedPtr {
    public:
     SharedPtr() = default;
@@ -70,13 +70,13 @@
   explicit CoefficientTableCache(fit::function<CoefficientTable*(const InputT&)> create_table)
       : create_table_(std::move(create_table)) {}
 
-  // Get returns a cached table for the given inputs, or if a cached tabled does not exist, a new
-  // table is created and stored in the cache.
+  // Returns a cached table for the given inputs, or if a cached tabled does not exist, a new table
+  // is created and stored in the cache.
   SharedPtr Get(InputT inputs) {
     return AddEntry(inputs, [this, inputs]() { return create_table_(inputs); });
   }
 
-  // Add is like Get, but uses the given table rather than creating a new one.
+  // Similar to `Get`, but uses the given table rather than creating a new one.
   SharedPtr Add(InputT inputs, CoefficientTable* table) {
     return AddEntry(inputs, [table]() { return table; });
   }
@@ -87,7 +87,7 @@
     // This allows multiple threads to create tables concurrently.
     mutex_.lock();
 
-    // std::map guarantees that iterators are not invalidated until erased.
+    // `std::map` guarantees that iterators are not invalidated until erased.
     // We hold onto this iterator until the reference is dropped.
     auto lookup_result = cache_.insert(std::make_pair(inputs, std::make_unique<Entry>()));
     auto it = lookup_result.first;
@@ -129,8 +129,8 @@
   fit::function<CoefficientTable*(InputT)> create_table_;
 };
 
-// LazySharedCoefficientTable is a wrapper around CoefficientTables that are constructed lazily.
-// This is a simple way to construct a CoefficientTable table in any thread (such as the FIDL loop
+// `LazySharedCoefficientTable` is a wrapper around `CoefficientTables` that are constructed lazily.
+// This is a simple way to construct a `CoefficientTable` table in any thread (such as the FIDL loop
 // thread) but delay the potentially-expensive step of building the table until the table is
 // actually needed, possibly on another thread.
 template <class InputT>
@@ -157,6 +157,6 @@
   typename CacheT::SharedPtr ptr_;
 };
 
-}  // namespace media::audio::mixer
+}  // namespace media_audio
 
 #endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_COEFFICIENT_TABLE_CACHE_H_
diff --git a/src/media/audio/audio_core/mixer/coefficient_table_cache_unittest.cc b/src/media/audio/lib/processing/coefficient_table_cache_unittest.cc
similarity index 93%
rename from src/media/audio/audio_core/mixer/coefficient_table_cache_unittest.cc
rename to src/media/audio/lib/processing/coefficient_table_cache_unittest.cc
index 24b1d29..7189fe5 100644
--- a/src/media/audio/audio_core/mixer/coefficient_table_cache_unittest.cc
+++ b/src/media/audio/lib/processing/coefficient_table_cache_unittest.cc
@@ -1,14 +1,16 @@
-// Copyright 2020 The Fuchsia Authors. All rights reserved.
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/media/audio/audio_core/mixer/coefficient_table_cache.h"
+#include "src/media/audio/lib/processing/coefficient_table_cache.h"
+
+#include <utility>
 
 #include <gtest/gtest.h>
 
-#include "src/media/audio/lib/format/constants.h"
+#include "src/media/audio/lib/format2/fixed.h"
 
-namespace media::audio::mixer {
+namespace media_audio {
 namespace {
 
 CoefficientTable* MakeCoefficientTable() {
@@ -111,4 +113,4 @@
 }
 
 }  // namespace
-}  // namespace media::audio::mixer
+}  // namespace media_audio
diff --git a/src/media/audio/lib/processing/coefficient_table_data_empty.cc b/src/media/audio/lib/processing/coefficient_table_data_empty.cc
new file mode 100644
index 0000000..afd2ca3
--- /dev/null
+++ b/src/media/audio/lib/processing/coefficient_table_data_empty.cc
@@ -0,0 +1,14 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <lib/stdcompat/span.h>
+
+#include "src/media/audio/lib/processing/coefficient_table.h"
+
+namespace media_audio {
+
+// This file is linked by builds that have no prebuilt coefficient tables.
+const cpp20::span<const PrebuiltSincFilterCoefficientTable> kPrebuiltSincFilterCoefficientTables;
+
+}  // namespace media_audio
diff --git a/src/media/audio/audio_core/mixer/coefficient_table_unittest.cc b/src/media/audio/lib/processing/coefficient_table_unittest.cc
similarity index 88%
rename from src/media/audio/audio_core/mixer/coefficient_table_unittest.cc
rename to src/media/audio/lib/processing/coefficient_table_unittest.cc
index d9d748f..dcf6121 100644
--- a/src/media/audio/audio_core/mixer/coefficient_table_unittest.cc
+++ b/src/media/audio/lib/processing/coefficient_table_unittest.cc
@@ -2,13 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
+#include "src/media/audio/lib/processing/coefficient_table.h"
 
 #include <gtest/gtest.h>
 
-#include "src/media/audio/lib/format/constants.h"
+#include "src/media/audio/lib/format2/fixed.h"
 
-namespace media::audio::mixer {
+namespace media_audio {
+namespace {
 
 TEST(CoefficientTableTest, AllIndicesAccessible) {
   Fixed width(10);
@@ -32,8 +33,8 @@
                          cpp20::span<const float>{});
 
   for (int64_t fraction = 0; fraction < kOneFrame.raw_value(); ++fraction) {
-    // Each fractional value will have a block in the vector. Now check that
-    // every valid integral value is contiguous for this fractional value.
+    // Each fractional value will have a block in the vector. Now check that every valid integral
+    // value is contiguous for this fractional value.
     auto block_index = fraction * width.Ceiling();
     for (int64_t integer = 0; integer < width.Ceiling(); ++integer) {
       auto fixed_value = (integer << Fixed::Format::FractionalBits) + fraction;
@@ -62,4 +63,5 @@
   }
 }
 
-}  // namespace media::audio::mixer
+}  // namespace
+}  // namespace media_audio
diff --git a/src/media/audio/audio_core/mixer/filter.cc b/src/media/audio/lib/processing/filter.cc
similarity index 88%
rename from src/media/audio/audio_core/mixer/filter.cc
rename to src/media/audio/lib/processing/filter.cc
index c6dd1d0..bf3a53a 100644
--- a/src/media/audio/audio_core/mixer/filter.cc
+++ b/src/media/audio/lib/processing/filter.cc
@@ -1,22 +1,31 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
-#include "src/media/audio/audio_core/mixer/filter.h"
+#include "src/media/audio/lib/processing/filter.h"
 
 #include <lib/syslog/cpp/macros.h>
 #include <lib/trace/event.h>
 #include <lib/zx/clock.h>
 
 #include <iomanip>
+#include <ios>
+#include <limits>
 #include <memory>
-#include <mutex>
+#include <vector>
 
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
-#include "src/media/audio/audio_core/mixer/logging_flags.h"
+#include "src/media/audio/lib/processing/coefficient_table.h"
 
-namespace media::audio::mixer {
+namespace media_audio {
 
-// Display the filter table values.
+namespace {
+
+// Debug computation of output values (`ComputeSample`), from coefficients and input values.
+// Extremely verbose, only useful in a controlled unittest setting.
+constexpr bool kTraceFilterComputation = false;
+
+}  // namespace
+
 void Filter::DisplayTable(const CoefficientTable& filter_coefficients) {
   FX_LOGS(INFO) << "Filter: source rate " << source_rate_ << ", dest rate " << dest_rate_
                 << ", length 0x" << std::hex << side_length_;
@@ -45,12 +54,12 @@
   FX_LOGS(INFO) << " **************************************************************";
 }
 
-// For frac_offset in [0.0, 1.0) we require source frames on each side depending on filter length.
-// Source frames are at integral positions, but we treat frac_offset as filter center, so source
+// For `frac_offset` in [0.0, 1.0) we require source frames on each side depending on filter length.
+// Source frames are at integral positions, but we treat `frac_offset` as filter center, so source
 // frames appear to be fractionally positioned.
 //
 // Filter coefficients cover the entire discrete space of fractional positions, but any calculation
-// references only a subset of these, using a one-frame stride (frac_size_). Coefficient tables
+// references only a subset of these, using a one-frame stride (`frac_size_`). Coefficient tables
 // internally store values with an integer stride contiguously, which is what these loops want.
 //   Ex:
 //     coefficient_ptr[1] == filter_coefficients[frac_offset + frac_size_];
@@ -167,23 +176,14 @@
   return cache;
 }
 
-// static
-PointFilter::CacheT* const PointFilter::cache_ =
-    new PointFilter::CacheT([](PointFilterCoefficientTable::Inputs inputs) {
-      TRACE_DURATION("audio", "CreatePointFilterTable");
-      return PointFilterCoefficientTable::Create(inputs).release();
-    });
-
-// static
 LinearFilter::CacheT* const LinearFilter::cache_ =
     new LinearFilter::CacheT([](LinearFilterCoefficientTable::Inputs inputs) {
       TRACE_DURATION("audio", "CreateLinearFilterTable");
       return LinearFilterCoefficientTable::Create(inputs).release();
     });
 
-// static
-// Must initialize persistent_cache_ first as it's used by the Create function.
+// Must initialize `persistent_cache_` first as it's used by the `Create` function.
 std::vector<SincFilter::CacheT::SharedPtr>* SincFilter::persistent_cache_ = nullptr;
 SincFilter::CacheT* const SincFilter::cache_ = CreateSincFilterCoefficientTableCache();
 
-}  // namespace media::audio::mixer
+}  // namespace media_audio
diff --git a/src/media/audio/audio_core/mixer/filter.h b/src/media/audio/lib/processing/filter.h
similarity index 68%
rename from src/media/audio/audio_core/mixer/filter.h
rename to src/media/audio/lib/processing/filter.h
index aefb8f0..6ee56b0 100644
--- a/src/media/audio/audio_core/mixer/filter.h
+++ b/src/media/audio/lib/processing/filter.h
@@ -1,28 +1,24 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
-#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_FILTER_H_
-#define SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_FILTER_H_
+#ifndef SRC_MEDIA_AUDIO_LIB_PROCESSING_FILTER_H_
+#define SRC_MEDIA_AUDIO_LIB_PROCESSING_FILTER_H_
 
 #include <lib/syslog/cpp/macros.h>
 
-#include <cmath>
-#include <memory>
 #include <vector>
 
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
-#include "src/media/audio/audio_core/mixer/coefficient_table_cache.h"
-#include "src/media/audio/audio_core/mixer/constants.h"
-#include "src/media/audio/lib/format/constants.h"
+#include "src/media/audio/lib/format2/fixed.h"
+#include "src/media/audio/lib/processing/coefficient_table.h"
+#include "src/media/audio/lib/processing/coefficient_table_cache.h"
 
-namespace media::audio::mixer {
+namespace media_audio {
 
 // This class represents a symmetric, convolution-based filter, to be applied to an audio stream.
-//
-// Param side_length is the number of subframes included on each side, including center subframe 0.
-// Child classes differ only in their filter coefficients.
 class Filter {
  public:
+  // `side_length` is the number of subframes included on each side, including center subframe 0.
   Filter(int32_t source_rate, int32_t dest_rate, int64_t side_length,
          int32_t num_frac_bits = Fixed::Format::FractionalBits)
       : source_rate_(source_rate),
@@ -37,8 +33,17 @@
     FX_DCHECK(num_frac_bits_ > 0);
   }
 
+  // Computes sample at `center` frame with `frac_offset`.
   virtual float ComputeSample(int64_t frac_offset, float* center) = 0;
 
+  // Displays the filter table values. Used for debugging purposes only.
+  virtual void Display() = 0;
+
+  // Eagerly precomputes needed data. If not called, needed data will be lazily computed on the
+  // first `ComputeSample` call.
+  // TODO(fxbug.dev/45074): This is for tests only and can be removed once filter creation is eager.
+  virtual void EagerlyPrepare() = 0;
+
   int32_t source_rate() const { return source_rate_; }
   int32_t dest_rate() const { return dest_rate_; }
   int64_t side_length() const { return side_length_; }
@@ -46,13 +51,6 @@
   int64_t frac_size() const { return frac_size_; }
   double rate_conversion_ratio() const { return rate_conversion_ratio_; }
 
-  // used for debugging purposes only
-  virtual void Display() = 0;
-
-  // Eagerly precompute needed data. If not called, lazily compute on the first ComputeSample() call
-  // TODO(fxbug.dev/45074): This is for tests only and can be removed once filter creation is eager.
-  virtual void EagerlyPrepare() = 0;
-
  protected:
   float ComputeSampleFromTable(const CoefficientTable& filter_coefficients, int64_t frac_offset,
                                float* center);
@@ -69,43 +67,13 @@
   double rate_conversion_ratio_;
 };
 
-// See PointFilterCoefficientTable.
-class PointFilter : public Filter {
- public:
-  PointFilter(int32_t source_rate, int32_t dest_rate,
-              int32_t num_frac_bits = Fixed::Format::FractionalBits)
-      : Filter(source_rate, dest_rate,
-               /* side_length= */ (1 << (num_frac_bits - 1)) + 1, num_frac_bits),
-        filter_coefficients_(cache_, Inputs{
-                                         .side_length = this->side_length(),
-                                         .num_frac_bits = this->num_frac_bits(),
-                                     }) {}
-
-  float ComputeSample(int64_t frac_offset, float* center) override {
-    return ComputeSampleFromTable(*filter_coefficients_, frac_offset, center);
-  }
-
-  void Display() override { DisplayTable(*filter_coefficients_); }
-
-  const float& operator[](int64_t index) { return (*filter_coefficients_)[index]; }
-
-  void EagerlyPrepare() override { filter_coefficients_.get(); }
-
- private:
-  using Inputs = PointFilterCoefficientTable::Inputs;
-  using CacheT = CoefficientTableCache<Inputs>;
-
-  static CacheT* const cache_;
-  LazySharedCoefficientTable<Inputs> filter_coefficients_;
-};
-
-// See LinearFilterCoefficientTable.
+// See `LinearFilterCoefficientTable`.
 class LinearFilter : public Filter {
  public:
   LinearFilter(int32_t source_rate, int32_t dest_rate,
                int32_t num_frac_bits = Fixed::Format::FractionalBits)
       : Filter(source_rate, dest_rate,
-               /* side_length= */ 1 << num_frac_bits, num_frac_bits),
+               /*side_length=*/1 << num_frac_bits, num_frac_bits),
         filter_coefficients_(cache_, Inputs{
                                          .side_length = this->side_length(),
                                          .num_frac_bits = this->num_frac_bits(),
@@ -129,7 +97,7 @@
   LazySharedCoefficientTable<Inputs> filter_coefficients_;
 };
 
-// See SincFilterCoefficientTable.
+// See `SincFilterCoefficientTable`.
 class SincFilter : public Filter {
  public:
   static constexpr auto kSideTaps = SincFilterCoefficientTable::kSideTaps;
@@ -171,6 +139,6 @@
   LazySharedCoefficientTable<Inputs> filter_coefficients_;
 };
 
-}  // namespace media::audio::mixer
+}  // namespace media_audio
 
 #endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_MIXER_FILTER_H_
diff --git a/src/media/audio/audio_core/mixer/filter_unittest.cc b/src/media/audio/lib/processing/filter_unittest.cc
similarity index 75%
rename from src/media/audio/audio_core/mixer/filter_unittest.cc
rename to src/media/audio/lib/processing/filter_unittest.cc
index 658b239..de59328 100644
--- a/src/media/audio/audio_core/mixer/filter_unittest.cc
+++ b/src/media/audio/lib/processing/filter_unittest.cc
@@ -1,59 +1,16 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
-#include "src/media/audio/audio_core/mixer/filter.h"
+#include "src/media/audio/lib/processing/filter.h"
 
 #include <lib/syslog/cpp/macros.h>
 
 #include <gtest/gtest.h>
 
-namespace media::audio::mixer {
+namespace media_audio {
 namespace {
 
-TEST(PointFilterTest, Construction) {
-  {
-    auto source_rate = 48000;
-    auto dest_rate = 48000;
-    int32_t expected_num_frac_bits = Fixed::Format::FractionalBits;  // default
-    PointFilter filter(source_rate, dest_rate);
-    auto expected_side_length = (1 << (expected_num_frac_bits - 1)) + 1;
-
-    EXPECT_EQ(filter.source_rate(), source_rate);
-    EXPECT_EQ(filter.dest_rate(), dest_rate);
-    EXPECT_EQ(filter.num_frac_bits(), expected_num_frac_bits);
-    EXPECT_EQ(filter.side_length(), expected_side_length);
-    EXPECT_DOUBLE_EQ(filter.rate_conversion_ratio(), 1.0);
-  }
-
-  {
-    auto source_rate = 16000;
-    auto dest_rate = 48000;
-    int32_t expected_num_frac_bits = Fixed::Format::FractionalBits;  // default
-    PointFilter filter(source_rate, dest_rate);
-    auto expected_side_length = (1 << (expected_num_frac_bits - 1)) + 1;
-
-    EXPECT_EQ(filter.source_rate(), source_rate);
-    EXPECT_EQ(filter.dest_rate(), dest_rate);
-    EXPECT_EQ(filter.num_frac_bits(), expected_num_frac_bits);
-    EXPECT_EQ(filter.side_length(), expected_side_length);
-    EXPECT_DOUBLE_EQ(filter.rate_conversion_ratio(), 3.0);
-  }
-
-  {
-    auto source_rate = 44100;
-    auto dest_rate = 22050;
-    int32_t num_frac_bits = 4;
-    PointFilter filter(source_rate, dest_rate, num_frac_bits);
-    auto expected_side_length = (1 << (num_frac_bits - 1)) + 1;
-
-    EXPECT_EQ(filter.source_rate(), source_rate);
-    EXPECT_EQ(filter.dest_rate(), dest_rate);
-    EXPECT_EQ(filter.num_frac_bits(), num_frac_bits);
-    EXPECT_EQ(filter.side_length(), expected_side_length);
-    EXPECT_DOUBLE_EQ(filter.rate_conversion_ratio(), 0.5);
-  }
-}
-
 TEST(LinearFilterTest, Construction) {
   {
     auto source_rate = 48000;
@@ -160,24 +117,6 @@
   }
 }
 
-TEST(PointFilterTest, FilterCoefficients) {
-  auto source_rate = 48000;
-  auto dest_rate = 48000;
-  int32_t num_frac_bits = 4;
-  PointFilter filter(source_rate, dest_rate, num_frac_bits);
-
-  const auto frac_half = 1 << (num_frac_bits - 1);
-  const auto expected_side_length = frac_half + 1;
-  EXPECT_EQ(filter.side_length(), expected_side_length);
-
-  EXPECT_FLOAT_EQ(filter[0], 1.0f);
-  for (auto idx = 1; idx < frac_half; ++idx) {
-    EXPECT_FLOAT_EQ(filter[idx], 1.0f);
-  }
-
-  EXPECT_FLOAT_EQ(filter[frac_half], 0.5f);
-}
-
 TEST(LinearFilterTest, FilterCoefficients) {
   auto source_rate = 48000;
   auto dest_rate = 48000;
@@ -252,22 +191,6 @@
   EXPECT_DOUBLE_EQ(filter.rate_conversion_ratio(), 2.0);
 }
 
-// TODO(mpuryear): validate other rate-conversion ratios
-TEST(PointFilterTest, ComputeSample) {
-  auto source_rate = 48000;
-  auto dest_rate = 48000;
-  int32_t num_frac_bits = 4;
-  auto frac_size = 1 << num_frac_bits;
-  auto frac_half = frac_size >> 1;
-  PointFilter filter(source_rate, dest_rate, num_frac_bits);
-
-  float data[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f};
-
-  EXPECT_FLOAT_EQ(filter.ComputeSample(0, &data[1]), data[1]);
-  EXPECT_FLOAT_EQ(filter.ComputeSample(frac_half, &data[2]), (data[2] + data[3]) / 2);
-  EXPECT_FLOAT_EQ(filter.ComputeSample(frac_size - 1, &data[3]), data[4]);
-}
-
 TEST(LinearFilterTest, ComputeSample) {
   auto source_rate = 48000;
   auto dest_rate = 48000;
@@ -289,7 +212,7 @@
                                int32_t num_frac_bits) {
   SincFilter filter(source_rate, dest_rate, side_length, num_frac_bits);
 
-  // If values outside indices [1,33] are used in ComputeSample, data compares will fail.
+  // If values outside indices [1,33] are used in `ComputeSample`, data compares will fail.
   float data[] = {
       999999.0f,                                             //
       0.1f,       0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f,  //
@@ -308,8 +231,8 @@
   SCOPED_TRACE("Compute(17.0) == [17]");
   EXPECT_FLOAT_EQ(filter.ComputeSample(0, &data[17]), data[17]);
 
-  // These values are only calculated to a specific quality tolerance (related to side_length and
-  // num_frac_bits), so the only SAFE things to do here are rough comparisons.
+  // These values are only calculated to a specific quality tolerance (related to `side_length` and
+  // `num_frac_bits`), so the only SAFE things to do here are rough comparisons.
   SCOPED_TRACE("[17] < Compute(17.25)");
   EXPECT_LT(data[17], filter.ComputeSample(frac_half, &data[17]));
 
@@ -359,4 +282,4 @@
 }
 
 }  // namespace
-}  // namespace media::audio::mixer
+}  // namespace media_audio
diff --git a/src/media/audio/audio_core/mixer/gen_coefficient_tables.cc b/src/media/audio/lib/processing/gen_coefficient_tables.cc
similarity index 82%
rename from src/media/audio/audio_core/mixer/gen_coefficient_tables.cc
rename to src/media/audio/lib/processing/gen_coefficient_tables.cc
index 1419c04..aff9a78 100644
--- a/src/media/audio/audio_core/mixer/gen_coefficient_tables.cc
+++ b/src/media/audio/lib/processing/gen_coefficient_tables.cc
@@ -8,14 +8,15 @@
 #include <iostream>
 #include <vector>
 
-#include "src/media/audio/audio_core/mixer/coefficient_table.h"
-
-using media::audio::Fixed;
-using media::audio::mixer::CoefficientTable;
-using media::audio::mixer::SincFilterCoefficientTable;
+#include "src/media/audio/lib/format2/fixed.h"
+#include "src/media/audio/lib/processing/coefficient_table.h"
 
 namespace {
 
+using ::media_audio::CoefficientTable;
+using ::media_audio::Fixed;
+using ::media_audio::SincFilterCoefficientTable;
+
 struct Key {
   int32_t source_rate;
   int32_t dest_rate;
@@ -41,16 +42,16 @@
   out << "//\n";
   out << "// Generated by gen_coefficient_tables.cc.\n";
   out << "\n";
-  out << "#include \"src/media/audio/audio_core/mixer/coefficient_table.h\"\n";
+  out << "#include \"src/media/audio/lib/processing/coefficient_table.h\"\n";
   out << "\n";
-  out << "namespace media::audio::mixer {\n";
+  out << "namespace media_audio {\n";
   out << "\n";
   out << "// Static asserts to validate that the generated code is not out-of-date\n";
-  out << "static_assert(media::audio::kPtsFractionalBits == " << Fixed::Format::FractionalBits
+  out << "static_assert(media_audio::kPtsFractionalBits == " << Fixed::Format::FractionalBits
       << ");\n";
-  out << "static_assert(media::audio::mixer::SincFilterCoefficientTable::kSideTaps == "
+  out << "static_assert(media_audio::SincFilterCoefficientTable::kSideTaps == "
       << SincFilterCoefficientTable::kSideTaps << ");\n";
-  out << "static_assert(media::audio::mixer::SincFilterCoefficientTable::kFracSideLength == "
+  out << "static_assert(media_audio::SincFilterCoefficientTable::kFracSideLength == "
       << SincFilterCoefficientTable::kFracSideLength << ");\n";
   out << "\n";
 
@@ -108,7 +109,7 @@
          "kPrebuiltSincFilterCoefficientTables(kPrebuiltTables, static_cast<size_t>("
       << tables.size() << "));\n";
   out << "\n";
-  out << "}  // namespace media::audio::mixer\n";
+  out << "}  // namespace media_audio\n";
 
   return 0;
 }
diff --git a/src/media/audio/lib/test/BUILD.gn b/src/media/audio/lib/test/BUILD.gn
index 23b4324f..e4b2f04 100644
--- a/src/media/audio/lib/test/BUILD.gn
+++ b/src/media/audio/lib/test/BUILD.gn
@@ -92,11 +92,11 @@
     "//sdk/lib/sys/inspect/cpp",
     "//sdk/lib/syslog/cpp",
     "//src/media/audio/audio_core:audio_core_lib",
-    "//src/media/audio/audio_core/mixer:prebuilt_coefficient_tables",
     "//src/media/audio/effects/test_effects:test_effects_v2",
     "//src/media/audio/lib/analysis",
     "//src/media/audio/lib/clock",
     "//src/media/audio/lib/format",
+    "//src/media/audio/lib/processing:prebuilt_coefficient_tables",
     "//src/media/audio/lib/wav",
     "//src/power/fidl/testing:test.thermal",
     "//third_party/googletest:gtest",