Add callback and playback timestamp implementation for webaudio stream

This commit is contained in:
mitchmindtree 2020-05-22 14:35:29 +02:00
parent 640a1d39ed
commit 78e1796ba8
3 changed files with 14 additions and 8 deletions

View File

@ -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).

View File

@ -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);

View File

@ -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<Self> {
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 }
}