secs_engine/lib.rs
1#![forbid(unsafe_code)]
2#![deny(unsafe_op_in_unsafe_fn)]
3//! The correction design of SECS 2, translated function by function.
4//!
5//! Upstream sources: `correction_engine.py`, the compute half of
6//! `calibration.py`, `mimo.py`, `mimo_iir.py`, `scorecard.py`.
7//!
8//! The interface is one call: measurements, settings, tuning and a compute
9//! context in, an immutable result out. Internally the work is cut into deep
10//! modules (docs/ARCHITECTURE.md, "Engine"):
11//!
12//! - **measurement**: the one time-axis convention (earliest arrival at the
13//! main position is zero, lift, shift), windows, a proper low-rate
14//! projection for MIMO.
15//! - **target**: target curve and level reference, evaluated once per grid.
16//! - **filters**: RBJ/LR/BW/all-pass responses and the single PEQ fitter with
17//! named limit bundles (RC, sub bus, bundle, XO, MIMO path).
18//! - **ba**: bass alignment (auto, fixed, bundles, DBA and multi-sub layouts,
19//! infra sub, two-way level match, bus level, bus PEQ, bus delay/polarity).
20//! - **xo**: crossover groups, XO target PEQ, the recommendation.
21//! - **rc**: per-channel room correction (magnitude design, common excess
22//! phase, FIR realisation ladder, PEQ refit, touch-up), Schroeder range.
23//! - **decay**: late-energy windows, mode T60, late peaks, "do no harm" guards.
24//! - **chain**: the DSP topology as one value; the response simulator here and
25//! the CamillaDSP writer in `secs-camilla` read the same value.
26//! - **mimo**: support planning, regularised ideal supports (the λ search of
27//! the ideal FIR goes through the `RidgeBackend` seam: CPU `RidgeSweep`
28//! here, CUDA f64 in `secs-gpu`, ADR 0008), IIR or FIR realisation (IIR
29//! always runs on the CPU).
30//! - **scorecard**: typed metrics before and after.
31//!
32//! Engine knobs that SECS 2 hid in environment variables are fields of an
33//! explicit tuning value. Defects fixed on the way are listed in
34//! docs/DEVIATIONS.md.
35
36pub mod grid;
37pub mod input;
38
39// The stages are private: `design` is the one entry point and the values it
40// returns are re-exported below. Helpers only the oracle tests call yet keep
41// the dead-code allowance.
42#[allow(dead_code)]
43mod ba;
44#[allow(dead_code)]
45mod calibration;
46#[allow(dead_code)]
47mod chain;
48#[allow(dead_code)]
49mod decay;
50#[allow(dead_code)]
51mod design;
52pub mod display;
53pub mod export_view;
54#[allow(dead_code)]
55mod fit;
56#[allow(dead_code)]
57mod levels;
58#[allow(dead_code)]
59mod measurement;
60mod memory;
61#[allow(dead_code)]
62pub mod mimo;
63mod normalize;
64#[allow(dead_code)]
65mod notes;
66pub mod preview;
67#[allow(dead_code)]
68mod rc;
69mod replay;
70mod replay_mimo;
71#[allow(dead_code)]
72mod scorecard;
73#[allow(dead_code)]
74mod setup;
75#[allow(dead_code)]
76pub mod xo;
77
78mod error;
79#[cfg(test)]
80pub mod test_support;
81#[cfg(feature = "test-support")]
82#[doc(hidden)]
83pub mod testkit;
84#[cfg(test)]
85mod tests;
86
87pub use ba::{LayoutInfo, ManualPlan};
88pub use calibration::{
89 Calibration, CalibrationRequest, EngineInputs, ProjectView, calibrate, calibrate_with,
90 engine_inputs,
91};
92pub use chain::{BaRow, StageResponses, input_response, stage_responses};
93pub use design::{
94 Design, DesignRequest, DesignSpectra, FitStage, FitterFactory, MainDesign, RoleLateEnergy,
95 RoleScores, SubDesign, design, late_energy, production_fitters, production_fitters_with,
96};
97pub use error::EngineError;
98pub use export_view::{ExportView, export_view};
99pub use fit::{FitRequest, Fitter, PeqDerivatives, fit_peq_with};
100pub use input::{EngineConfig, Measurement, MeasurementSet, Samples, Tuning};
101pub use measurement::{Spectra, long_spectra};
102pub use mimo::{
103 IirDerivatives, IirSolveOptions, IirSolver, IirSupport, MimoDesign, MimoIir, MimoKey,
104 MimoRequest, MimoRoleLateEnergy, MimoRoleScore, MimoRun, design_mimo, design_mimo_iir,
105 design_mimo_iir_with_options,
106};
107pub use normalize::normalize_measurements;
108pub use notes::{MimoNote, Note};
109pub use replay::{DesignReplay, ExportAxis};
110pub use scorecard::Metrics;
111pub use secs_dsp::resample::{MAX_RESAMPLE_RATE, MIN_RESAMPLE_RATE};
112pub use setup::SubFilter;
113
114/// Complex spectrum value.
115pub type C = secs_dsp::Complex64;