From 78e1796ba8d6fc10e51801d2f5fa2b58016328c4 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Fri, 22 May 2020 14:35:29 +0200 Subject: [PATCH] Add callback and playback timestamp implementation for webaudio stream --- src/host/emscripten/mod.rs | 6 +----- src/host/webaudio/mod.rs | 7 ++++--- src/lib.rs | 9 +++++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/host/emscripten/mod.rs b/src/host/emscripten/mod.rs index d3a31bd..de5ac0a 100644 --- a/src/host/emscripten/mod.rs +++ b/src/host/emscripten/mod.rs @@ -248,11 +248,7 @@ where let now_secs: f64 = js!(@{audio_ctxt}.getOutputTimestamp().currentTime) .try_into() .expect("failed to retrieve Value as f64"); - let callback = { - let secs = now_secs as i64; - let nanos = ((now_secs * 1_000_000_000.0) - secs as f64 * 1_000_000_000.0) as u32; - crate::StreamInstant::new(secs, nanos) - }; + let callback = crate::StreamInstant::from_secs_f64(now_secs); // TODO: Use proper latency instead. Currently unsupported on most browsers though so // we estimate based on buffer size instead. Probably should use this, but it's only // supported by firefox (2020-04-28). diff --git a/src/host/webaudio/mod.rs b/src/host/webaudio/mod.rs index 8b2f293..2d27dff 100644 --- a/src/host/webaudio/mod.rs +++ b/src/host/webaudio/mod.rs @@ -242,6 +242,7 @@ impl DeviceTrait for Device { .write() .unwrap() .replace(Closure::wrap(Box::new(move || { + let now = ctx_handle.current_time(); let time_at_start_of_buffer = { let time_at_start_of_buffer = time_handle .read() @@ -251,7 +252,7 @@ impl DeviceTrait for Device { *time_at_start_of_buffer } else { // 25ms of time to fetch the first sample data, increase to avoid initial underruns. - ctx_handle.current_time() + 0.025 + now + 0.025 } }; @@ -262,8 +263,8 @@ impl DeviceTrait for Device { let sample_format = SampleFormat::F32; let mut data = unsafe { Data::from_parts(data, len, sample_format) }; let mut data_callback = data_callback_handle.lock().unwrap(); - let callback = unimplemented!(); - let playback = unimplemented!(); + let callback = crate::StreamInstant::from_secs_f64(now); + let playback = crate::StreamInstant::from_secs_f64(time_at_start_of_buffer); let timestamp = crate::OutputStreamTimestamp { callback, playback }; let info = OutputCallbackInfo { timestamp }; (data_callback.deref_mut())(&mut data, &info); diff --git a/src/lib.rs b/src/lib.rs index 79cefe7..1c3e2c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -341,12 +341,14 @@ impl StreamInstant { (self.secs as i128 * 1_000_000_000) + self.nanos as i128 } + #[allow(dead_code)] fn from_nanos(nanos: i64) -> Self { let secs = nanos / 1_000_000_000; let subsec_nanos = nanos - secs * 1_000_000_000; Self::new(secs as i64, subsec_nanos as u32) } + #[allow(dead_code)] fn from_nanos_i128(nanos: i128) -> Option { let secs = nanos / 1_000_000_000; if secs > std::i64::MAX as i128 || secs < std::i64::MIN as i128 { @@ -358,6 +360,13 @@ impl StreamInstant { } } + #[allow(dead_code)] + fn from_secs_f64(secs: f64) -> crate::StreamInstant { + let s = secs.floor() as i64; + let ns = ((secs - s as f64) * 1_000_000_000.0) as u32; + Self::new(s, ns) + } + fn new(secs: i64, nanos: u32) -> Self { StreamInstant { secs, nanos } }