Offline modal analysis of a rendered impulse response or note: recover the resonant modes (frequency, T60, amplitude), track partials and measure inharmonicity, and resolve a single quasi-sinusoidal note's f0(t), decay rate sigma(t) and Q(t) cycle by cycle. More...
#include <cstddef>#include <span>#include <string>#include <vector>#include <pulp/signal/modal_spec.hpp>Go to the source code of this file.
Namespaces | |
| namespace | pulp |
| namespace | pulp::test |
| namespace | pulp::test::audio |
Functions | |
| ModeAnalysis | pulp::test::audio::analyze_modes (std::span< const float > ir, double sample_rate, const ModeAnalysisOptions &options={}) |
| Recover the modes present in ir, a rendered impulse response (mono). | |
| MeasuredMode | pulp::test::audio::measure_mode (std::span< const float > ir, double sample_rate, double guess_hz, const ModeAnalysisOptions &options={}) |
| Measure one mode whose frequency is already known approximately. | |
| std::string | pulp::test::audio::summarize (const ModeAnalysis &analysis) |
| One-line human-readable summary of a mode analysis, for INFO() in a test. | |
| std::string | pulp::test::audio::summarize (const MeasuredMode &mode) |
| InharmonicityResult | pulp::test::audio::measure_inharmonicity (std::span< const float > signal, double sample_rate, double f0_guess, const InharmonicityOptions &options={}) |
| Track the partials of signal starting from f0_guess and measure the inharmonicity. | |
| std::string | pulp::test::audio::summarize (const InharmonicityResult &result) |
| CycleTrack | pulp::test::audio::track_cycles (std::span< const float > signal, double sample_rate, const CycleTrackOptions &options={}) |
| Track f0(t), sigma(t) and Q(t) of a decaying quasi-sinusoidal note, cycle by cycle. | |
| Ar2Track | pulp::test::audio::track_ar2 (std::span< const float > signal, double sample_rate, const Ar2TrackOptions &options={}) |
| std::string | pulp::test::audio::summarize (const CycleTrack &track) |
| std::string | pulp::test::audio::summarize (const Ar2Track &track) |
| double | pulp::test::audio::windowed_magnitude (std::span< const float > x, std::size_t start, std::size_t length, double freq_hz, double sample_rate) |
| Hann-windowed DFT magnitude of x[start .
| |
| ModalExtractionResult | pulp::test::audio::compile_modal_spec (std::span< const float > impulse, double sample_rate, const ModalExtractionOptions &options={}) |
| Compile a bounded, mono impulse response into the existing ModalSpec data model. | |
Offline modal analysis of a rendered impulse response or note: recover the resonant modes (frequency, T60, amplitude), track partials and measure inharmonicity, and resolve a single quasi-sinusoidal note's f0(t), decay rate sigma(t) and Q(t) cycle by cycle.
This is the measurement side of physical modelling. A resonator is specified as modes; this header reads the modes back out of what the resonator actually emitted, so "did it do what I asked" is a number rather than a spectrogram someone squints at.
Shipped offline/tool layer only — every entry point analyzes a buffer that has already left the audio thread. Nothing here is realtime-safe, and this target must not be pulled into an audio processor merely because it is installed as part of the SDK.
Layering (test/support/README.md): this sits at the metrics layer. It takes plain buffers and returns facts; it never renders and never asserts. It depends only on pulp::audio-analysis (for the discovery FFT) and the standard library — no scenario or contract knowledge.
── Analyzer determinism contract ───────────────────────────────────────── Every measurement below is deterministic for identical input on a given platform: no randomness, no clocks, no threading, no platform math beyond IEEE-754 double. Mode discovery runs one Hann-windowed FFT (via magnitude_spectrum_curve); everything after it is an exact-frequency Hann-windowed DFT probe plus least-squares fits, which are FFT-backend independent. Discovery only nominates candidate frequencies — the reported numbers all come from the refinement stage — so a backend that shifts a peak by a fraction of a bin cannot move a result outside its tolerance.
── Stated limits (read these before trusting a number) ───────────────────
── Calibration ─────────────────────────────────────────────────────────── The estimators here are calibrated against synthetic signals with known ground truth in test/test_modal_analysis.cpp, including the control that makes the sigma/Q results usable: a constant-sigma signal carrying a prescribed frequency glide must recover sigma dead flat. An estimator that invents decay variation from a frequency glide would manufacture exactly the state-dependent-Q result one hopes to find. Any change to this file must keep that test green.