pub struct AudioLatencyMeasurementService;Expand description
Stateless facade that groups all latency measurement operations.
Every method takes a shared reference to an AudioService (or a raw
AudioHandlerTrait for round-trip) so the caller can hold whichever lock
granularity is appropriate. None of the methods start or stop the loopback.
Implementations§
Source§impl AudioLatencyMeasurementService
impl AudioLatencyMeasurementService
Sourcepub fn measure_gain_latency(
audio_service: &AudioService,
block_size: usize,
) -> f64
pub fn measure_gain_latency( audio_service: &AudioService, block_size: usize, ) -> f64
Measures the CPU execution cost added by the GainProcessor in the current channel.
Internally this benchmarks the gain processor against a zero-work passthrough over
iterations × block_size samples and returns the net cost — i.e. the passthrough
baseline is subtracted so the result isolates the processor’s own work.
§Arguments
audio_service— Service snapshot used to read the current channel’s gain arc.block_size— Number of samples per iteration. Larger values reduce timer overhead noise; 2 048 is the recommended default for command calls.
§Returns
Added execution cost in microseconds per sample (µs/sample), clamped to ≥ 0.
Sourcepub fn measure_tone_stack_latency(
audio_service: &AudioService,
block_size: usize,
) -> f64
pub fn measure_tone_stack_latency( audio_service: &AudioService, block_size: usize, ) -> f64
Measures the CPU execution cost added by the ToneStackProcessor in the current channel.
Uses the same baseline-subtraction methodology as measure_gain_latency: the result
is the net cost of the biquad filter chain, not the total wall-clock time per sample.
§Arguments
audio_service— Service snapshot used to read the current channel’s tone-stack arc.block_size— Number of samples per benchmark iteration.
§Returns
Added execution cost in microseconds per sample (µs/sample), clamped to ≥ 0.
Sourcepub fn measure_volume_latency(
audio_service: &AudioService,
block_size: usize,
) -> f64
pub fn measure_volume_latency( audio_service: &AudioService, block_size: usize, ) -> f64
Measures the CPU execution cost added by the per-channel volume GainProcessor.
The channel volume is a separate gain stage that sits after the tone stack and before
the master volume in the DSP chain. Its cost is benchmarked the same way as the
input gain — baseline-subtracted and clamped to ≥ 0.
§Arguments
audio_service— Service snapshot used to read the current channel’s volume arc.block_size— Number of samples per benchmark iteration.
§Returns
Added execution cost in microseconds per sample (µs/sample), clamped to ≥ 0.
Sourcepub fn measure_all_dsp_timings(
audio_service: &AudioService,
block_size: usize,
) -> Vec<ExecutionTimingDto>
pub fn measure_all_dsp_timings( audio_service: &AudioService, block_size: usize, ) -> Vec<ExecutionTimingDto>
Measures the CPU execution cost of every processor in the active DSP chain.
Runs individual benchmarks for all four processors in signal-chain order and returns the results as a vector.
§Arguments
audio_service— Service snapshot providing channel and master-volume arcs.block_size— Number of samples per benchmark iteration (recommended: 2 048).
§Returns
A Vec<ExecutionTimingDto> with exactly four entries, in signal-chain order:
| Index | Processor |
|---|---|
| 0 | Gain |
| 1 | Tone Stack |
| 2 | Volume |
| 3 | Master Volume |
Sourcepub fn measure_all_dsp_algorithmic_latency(
audio_service: &AudioService,
) -> Vec<AlgorithmicLatencyDto>
pub fn measure_all_dsp_algorithmic_latency( audio_service: &AudioService, ) -> Vec<AlgorithmicLatencyDto>
Returns the algorithmic (design-inherent) delay for every processor in the DSP chain.
For the current chain (Gain → Tone Stack → Volume → Master Volume) every processor is a sample-by-sample filter with no lookahead or delay line, so all values are zero.
§Arguments
audio_service— Used only to read the output sample rate for ms conversion.
§Returns
A Vec<AlgorithmicLatencyDto> with exactly four entries (Gain, Tone Stack, Volume,
Master Volume), each reporting latency_samples = 0 and latency_ms = 0.0.
Sourcepub fn measure_buffer_latency(audio_service: &AudioService) -> BufferLatencyDto
pub fn measure_buffer_latency(audio_service: &AudioService) -> BufferLatencyDto
Estimates the I/O buffer latency from the current CPAL stream configuration.
Buffer latency is the delay introduced by the hardware frame buffers: each side accumulates a full buffer of samples before the driver delivers or accepts them. The formula is:
latency_ms = (buffer_frames / sample_rate_hz) × 1000When CPAL is configured with BufferSize::Default the actual frame count is
unknown at runtime. In that case a conservative fallback of 256 frames is
used so the UI can display a practical estimate rather than zero or an error.
§Arguments
audio_service— Used to read both stream configs and sample rates.
§Returns
A BufferLatencyDto containing input_buffer_latency_ms,
output_buffer_latency_ms, and their sum as total_buffer_latency_ms.
Sourcepub fn measure_round_trip_latency(
handler: &dyn AudioHandlerTrait,
) -> RoundTripLatencyDto
pub fn measure_round_trip_latency( handler: &dyn AudioHandlerTrait, ) -> RoundTripLatencyDto
Measures true end-to-end round-trip latency using a dedicated pair of CPAL streams.
Unlike the other measurement functions this one performs a real-world, hardware
measurement rather than an analytical estimate. It delegates to
RoundTripLatencySession::run, which:
- Opens its own private input/output CPAL streams — completely separate from the main loopback.
- Warms up the streams for 1.5 s so the OS audio stack stabilises.
- Calibrates a detection threshold from ambient noise.
- Injects three impulses and times how long each takes to return on the input.
- Returns the average of the three round-trip durations.
The caller (measure_round_trip_latency Tauri command) is responsible for releasing
the Mutex<AudioService> lock and spawning a dedicated thread before calling this
function, so the main audio engine and UI remain responsive throughout.
§Arguments
handler— The audio I/O factory cloned fromAudioServicebefore the mutex was released. Used only to open the temporary measurement streams.
§Returns
A RoundTripLatencyDto with is_valid = true and latency_ms set on success,
or is_valid = false and a human-readable error message on failure.
§Physical requirement
The audio output must be physically (or virtually) looped back into the input for the echo to be detectable. If it is not, the measurement times out and returns an error explaining the likely cause.