Build and run

Build the library, run the smoke tests, and reproduce the benchmark data.

The project is a CMake-based C++17 codebase with a small benchmark CLI and a Python analysis step that turns benchmark CSVs into plots and a narrative report. The commands below match the repository layout directly.

Build The C++ Targets

cmake -S . -B build
cmake --build build --config Debug
ctest --test-dir build -C Debug

The build creates the reusable ANC library, the benchmark CLI, and the smoke-test executables declared in the top-level CMake project.

Run A Benchmark From The CLI

build\Debug\anc_cli.exe `
  --algorithm fxlms `
  --summary analysis_output\raw\fxlms_broadband_summary.csv `
  --timeseries analysis_output\raw\fxlms_broadband_timeseries.csv `
  --samples 12000 `
  --controller-order 48 `
  --step-size 0.005 `
  --convergence-window 256 `
  --sample-rate-hz 2000 `
  --waveform broadband

The CLI accepts the same option family across the implemented controllers. The common benchmark option surface includes sample count, controller order, LMS step sizes, leakage, secondary-path scaling, feedback-path scaling, waveform selection, and an optional external CSV trace via --input-trace.

Generate The Analysis Report

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r analysis\requirements.txt
python analysis\run_report.py

That step regenerates the benchmark CSVs, plots, and the report now published into this docs site.

Use The Controllers From C++

Every algorithm follows the same basic execution rhythm:

  1. Create a config struct with controller-specific parameters.
  2. Construct the controller.
  3. For each sample, call synthesize(...) to produce the control output.
  4. Feed the resulting error measurement into adapt(error).

A minimal FXLMS sketch looks like this:

#include "anc/fxlms_controller.h"

anc::FxlmsConfig config;
config.controllerOrder = 48;
config.secondaryEstimate = {0.0, 0.12, 0.38, 0.21, -0.05};
config.stepSize = 0.005;
config.leakage = 1.0;

anc::FxlmsController controller(config);

for (std::size_t sample = 0; sample < reference.size(); ++sample) {
  const double control = controller.synthesize(reference[sample]);
  const double error = disturbance[sample] + secondaryPathModel(control);
  controller.adapt(error);
}

Where To Go Next

Algorithms

Use the algorithm pages for equations, benchmark interpretation, and controller-specific C++ examples.

Browse the algorithm guide

Comparison

Use the comparison page when you need to decide which controller fits broadband, narrowband, feedback-contaminated, or drifting disturbances.

Open the comparison page