Increase realtime display transport rate
This commit is contained in:
@@ -37,5 +37,5 @@ metrics.addEventListener('message', (event) => {
|
|||||||
await new Promise((resolve) => setTimeout(resolve, 1100));
|
await new Promise((resolve) => setTimeout(resolve, 1100));
|
||||||
sockets.forEach((socket) => socket.close());
|
sockets.forEach((socket) => socket.close());
|
||||||
assert.equal(invalidPayload, false, 'metrics must be ordered and contain no large visual payloads');
|
assert.equal(invalidPayload, false, 'metrics must be ordered and contain no large visual payloads');
|
||||||
assert.ok(count >= 50 && count <= 75, `expected about 60 metrics/s, received ${count}`);
|
assert.ok(count >= 110 && count <= 145, `expected about 120 metrics/s, received ${count}`);
|
||||||
console.log(`runtime websocket test passed (${count} metrics in 1.1 s; max frame age ${maxFrameAgeMs} ms; all three streams opened)`);
|
console.log(`runtime websocket test passed (${count} metrics in 1.1 s; max frame age ${maxFrameAgeMs} ms; all three streams opened)`);
|
||||||
|
|||||||
+8
-3
@@ -40,8 +40,12 @@ use crate::{
|
|||||||
model::{InputSource, MeterFrame, PhoenixRtaConfig},
|
model::{InputSource, MeterFrame, PhoenixRtaConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
// Keep transport sampling safely above the 60 Hz display cadence. ALSA only
|
||||||
const METRICS_TARGET_UPDATES_PER_SECOND: u32 = 60;
|
// exposes complete capture periods, so a 60 Hz target with 128-frame periods
|
||||||
|
// alternates between roughly 16.0 and 18.7 ms at 48 kHz. A 120 Hz snapshot
|
||||||
|
// clock guarantees at least one fresh native state per display frame without
|
||||||
|
// changing any detector or ballistic calculation.
|
||||||
|
const METRICS_TARGET_UPDATES_PER_SECOND: u32 = 120;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
struct TransportPeaks {
|
struct TransportPeaks {
|
||||||
@@ -415,7 +419,8 @@ pub fn spawn_audio_capture_worker(deps: AudioWorkerDeps) {
|
|||||||
pub fn spawn_audio_capture_worker(deps: AudioWorkerDeps) {
|
pub fn spawn_audio_capture_worker(deps: AudioWorkerDeps) {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
warn!("Phoenix ALSA capture is only available on Linux; emitting placeholder frames on this host");
|
warn!("Phoenix ALSA capture is only available on Linux; emitting placeholder frames on this host");
|
||||||
let mut ticker = tokio::time::interval(Duration::from_millis(16));
|
let tick_ns = 1_000_000_000u64 / u64::from(METRICS_TARGET_UPDATES_PER_SECOND);
|
||||||
|
let mut ticker = tokio::time::interval(Duration::from_nanos(tick_ns));
|
||||||
deps.actual_sample_rate
|
deps.actual_sample_rate
|
||||||
.store(deps.config.sample_rate as u64, Ordering::SeqCst);
|
.store(deps.config.sample_rate as u64, Ordering::SeqCst);
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -58,6 +58,31 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn double_rate_transport_never_leaves_a_sixty_hz_display_interval_empty() {
|
||||||
|
let sample_rate = 48_000u32;
|
||||||
|
let period = 128usize;
|
||||||
|
let mut clock = GoniometerClock::default();
|
||||||
|
let mut processed = 0usize;
|
||||||
|
let mut previous_emission = None;
|
||||||
|
let mut largest_gap = 0usize;
|
||||||
|
|
||||||
|
while processed < sample_rate as usize * 10 {
|
||||||
|
processed += period;
|
||||||
|
if clock.advance(period, sample_rate, 120) {
|
||||||
|
if let Some(previous) = previous_emission {
|
||||||
|
largest_gap = largest_gap.max(processed - previous);
|
||||||
|
}
|
||||||
|
previous_emission = Some(processed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
largest_gap <= sample_rate as usize / 60,
|
||||||
|
"largest transport gap was {largest_gap} samples"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn selection_never_upsamples_and_keeps_endpoints() {
|
fn selection_never_upsamples_and_keeps_endpoints() {
|
||||||
assert_eq!(selected_sample_indices(3, 1024), vec![0, 1, 2]);
|
assert_eq!(selected_sample_indices(3, 1024), vec![0, 1, 2]);
|
||||||
|
|||||||
Reference in New Issue
Block a user