Measured-versus-reported latency: the evidence schema and its pure evaluators. More...
#include <pulp/audio/analysis/audio_metrics.hpp>#include <pulp/audio/buffer.hpp>#include <cstdint>#include <optional>#include <string>Go to the source code of this file.
Classes | |
| struct | pulp::test::audio::LatencyEvidence |
| One processor's latency evidence: the facts, the measurement, the verdict. More... | |
| struct | pulp::test::audio::DelayedNullOptions |
| Knobs for measure_delayed_passthrough. More... | |
| struct | pulp::test::audio::MarkerOffsetOptions |
| Knobs for measure_marker_offset. More... | |
Namespaces | |
| namespace | pulp |
| namespace | pulp::test |
| namespace | pulp::test::audio |
Functions | |
| LatencyEvidence | pulp::test::audio::measure_delayed_passthrough (const pulp::audio::Buffer< float > &input, const pulp::audio::Buffer< float > &output, std::optional< int > reported_samples, const DelayedNullOptions &options={}) |
| Sweep the delay D that best explains output as a copy of input, and compare it against reported_samples. | |
| LatencyEvidence | pulp::test::audio::measure_marker_offset (const pulp::audio::Buffer< float > &input, const pulp::audio::Buffer< float > &output, std::optional< int > reported_samples, const MarkerOffsetOptions &options={}) |
| Measure delay as output_onset - input_marker - intrinsic_response_offset and compare it against reported_samples. | |
| LatencyEvidence & | pulp::test::audio::apply_report_observation (LatencyEvidence &evidence) |
| Fold a report-observation fact into already-measured evidence. | |
| LatencyEvidence & | pulp::test::audio::apply_expected_samples (LatencyEvidence &evidence, int expected, std::int64_t tolerance_samples=0) |
| Additionally require the latency to equal expected, pinning the value rather than only its self-consistency. | |
| const char * | pulp::test::audio::to_string (LatencyReportStatus status) |
| const char * | pulp::test::audio::to_string (LatencyReportObservation observation) |
| const char * | pulp::test::audio::to_string (LatencyObservationMode mode) |
| const char * | pulp::test::audio::to_string (LatencyPolicy policy) |
| const char * | pulp::test::audio::to_string (LatencyMeasurementStatus status) |
| const char * | pulp::test::audio::to_string (LatencyContractOutcome outcome) |
| std::string | pulp::test::audio::latency_evidence_to_json (const LatencyEvidence &evidence) |
| Serialize evidence to a JSON object string. | |
| std::string | pulp::test::audio::latency_evidence_summary (const LatencyEvidence &evidence) |
| One-line human summary, suitable for a test failure message. | |
Variables | |
| constexpr int | pulp::test::audio::kLatencyEvidenceSchemaVersion = 1 |
| Schema version of the emitted object. Bump on any breaking field change. | |
Measured-versus-reported latency: the evidence schema and its pure evaluators.
A processor with nonzero latency tells its host a number (Processor::latency_samples()), and the host slides the whole track by that number to keep it aligned with everything else in the session. Nothing verifies the number. If the true delay through the processor and the reported delay drift apart — someone changes an FFT size, adds a filter stage, tweaks an oversampling ratio — the plugin quietly misaligns against every other track, and no test fails. This header makes "the reported latency is honest" a machine-checkable claim.
Report, measurement, and verdict are three separate things and are never collapsed into one another:
Ambiguity is never a pass. A stimulus that cannot pin the delay down — silence, a tone whose period is a whole number of samples (delays one period apart then produce bit-identical output), an output that is not a delayed copy of the input at all — yields not_measurable and inconclusive, never match. Instruments, generators, and arbitrary nonlinear or time-varying effects are not_measurable unless their author supplies a scenario that makes the delay observable.
The guard is not blanket paranoia about tones: a 440 Hz sine at 48 kHz has a 109.09-sample period, so no other integer delay reproduces it and the delay IS determined. It is integer-sample periodicity that destroys the information. A broadband, aperiodic stimulus (an impulse or noise) sidesteps the question entirely and is what these policies want.
The evaluators here are pure functions over buffers: no processor, no host, no I/O. Tests, the pulp CLI, and MCP all call these same functions and serialize this same struct, so a verdict cannot mean one thing in a test and another on the command line.
Test/tool layer only — never realtime-safe, never called from an audio callback.