add output latency to stats

This commit is contained in:
Hailey Somerville 2023-12-24 20:49:39 +11:00
parent 3b7fc96170
commit 81c8725038
3 changed files with 16 additions and 4 deletions

View file

@ -12,6 +12,7 @@ pub struct ReceiverStats {
audio_latency: f64, audio_latency: f64,
buffer_length: f64, buffer_length: f64,
output_latency: f64,
network_latency: f64, network_latency: f64,
predict_offset: f64, predict_offset: f64,
} }
@ -52,6 +53,7 @@ bitflags! {
const HAS_BUFFER_LENGTH = 0x08; const HAS_BUFFER_LENGTH = 0x08;
const HAS_NETWORK_LATENCY = 0x10; const HAS_NETWORK_LATENCY = 0x10;
const HAS_PREDICT_OFFSET = 0x20; const HAS_PREDICT_OFFSET = 0x20;
const HAS_OUTPUT_LATENCY = 0x40;
} }
} }
@ -86,11 +88,16 @@ impl ReceiverStats {
self.field(ReceiverStatsFlags::HAS_AUDIO_LATENCY, self.audio_latency) self.field(ReceiverStatsFlags::HAS_AUDIO_LATENCY, self.audio_latency)
} }
/// Duration of buffered audio in seconds /// Length of Bark-internal audio buffer in seconds
pub fn buffer_length(&self) -> Option<f64> { pub fn buffer_length(&self) -> Option<f64> {
self.field(ReceiverStatsFlags::HAS_BUFFER_LENGTH, self.buffer_length) self.field(ReceiverStatsFlags::HAS_BUFFER_LENGTH, self.buffer_length)
} }
/// Length of output audio buffer (including hardware latency) in seconds
pub fn output_latency(&self) -> Option<f64> {
self.field(ReceiverStatsFlags::HAS_OUTPUT_LATENCY, self.output_latency)
}
/// Duration of buffered audio in seconds /// Duration of buffered audio in seconds
pub fn network_latency(&self) -> Option<f64> { pub fn network_latency(&self) -> Option<f64> {
self.field(ReceiverStatsFlags::HAS_NETWORK_LATENCY, self.network_latency) self.field(ReceiverStatsFlags::HAS_NETWORK_LATENCY, self.network_latency)
@ -114,6 +121,11 @@ impl ReceiverStats {
self.flags.insert(ReceiverStatsFlags::HAS_BUFFER_LENGTH); self.flags.insert(ReceiverStatsFlags::HAS_BUFFER_LENGTH);
} }
pub fn set_output_latency(&mut self, latency: SampleDuration) {
self.output_latency = latency.to_std_duration_lossy().as_micros() as f64 / 1_000_000.0;
self.flags.insert(ReceiverStatsFlags::HAS_OUTPUT_LATENCY);
}
pub fn set_network_latency(&mut self, latency: core::time::Duration) { pub fn set_network_latency(&mut self, latency: core::time::Duration) {
self.network_latency = latency.as_micros() as f64 / 1_000_000.0; self.network_latency = latency.as_micros() as f64 / 1_000_000.0;
self.flags.insert(ReceiverStatsFlags::HAS_NETWORK_LATENCY); self.flags.insert(ReceiverStatsFlags::HAS_NETWORK_LATENCY);

View file

@ -225,7 +225,7 @@ impl RateAdjust {
fn adjusted_rate(&mut self, timing: Timing) -> Option<SampleRate> { fn adjusted_rate(&mut self, timing: Timing) -> Option<SampleRate> {
// parameters, maybe these could be cli args? // parameters, maybe these could be cli args?
let start_slew_threshold = Duration::from_micros(3000); let start_slew_threshold = Duration::from_micros(2000);
let stop_slew_threshold = Duration::from_micros(1000); let stop_slew_threshold = Duration::from_micros(1000);
let slew_target_duration = Duration::from_millis(500); let slew_target_duration = Duration::from_millis(500);
@ -327,13 +327,12 @@ pub fn run(opt: ReceiveOpt) -> Result<(), RunError> {
let mut state = state.lock().unwrap(); let mut state = state.lock().unwrap();
let delay = output.delay().unwrap(); let delay = output.delay().unwrap();
state.recv.stats.set_output_latency(delay);
let pts = time::now(); let pts = time::now();
let pts = Timestamp::from_micros_lossy(pts); let pts = Timestamp::from_micros_lossy(pts);
let pts = pts.add(delay); let pts = pts.add(delay);
println!("delay = {delay:?}");
// this should be large enough for `write_audio` to process an // this should be large enough for `write_audio` to process an
// entire packet with: // entire packet with:
let mut buffer = [0f32; SAMPLES_PER_PACKET * 2]; let mut buffer = [0f32; SAMPLES_PER_PACKET * 2];

View file

@ -56,6 +56,7 @@ fn receiver(out: &mut dyn WriteColor, stats: &ReceiverStats) {
time_field(out, "Audio", stats.audio_latency()); time_field(out, "Audio", stats.audio_latency());
time_field(out, "Buffer", stats.buffer_length()); time_field(out, "Buffer", stats.buffer_length());
time_field(out, "Output", stats.output_latency());
time_field(out, "Network", stats.network_latency()); time_field(out, "Network", stats.network_latency());
time_field(out, "Predict", stats.predict_offset()); time_field(out, "Predict", stats.predict_offset());
} }