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) let now_secs: f64 = js!(@{audio_ctxt}.getOutputTimestamp().currentTime)
.try_into() .try_into()
.expect("failed to retrieve Value as f64"); .expect("failed to retrieve Value as f64");
let callback = { let callback = crate::StreamInstant::from_secs_f64(now_secs);
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)
};
// TODO: Use proper latency instead. Currently unsupported on most browsers though so // 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 // we estimate based on buffer size instead. Probably should use this, but it's only
// supported by firefox (2020-04-28). // supported by firefox (2020-04-28).

View File

@ -242,6 +242,7 @@ impl DeviceTrait for Device {
.write() .write()
.unwrap() .unwrap()
.replace(Closure::wrap(Box::new(move || { .replace(Closure::wrap(Box::new(move || {
let now = ctx_handle.current_time();
let time_at_start_of_buffer = { let time_at_start_of_buffer = {
let time_at_start_of_buffer = time_handle let time_at_start_of_buffer = time_handle
.read() .read()
@ -251,7 +252,7 @@ impl DeviceTrait for Device {
*time_at_start_of_buffer *time_at_start_of_buffer
} else { } else {
// 25ms of time to fetch the first sample data, increase to avoid initial underruns. // 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 sample_format = SampleFormat::F32;
let mut data = unsafe { Data::from_parts(data, len, sample_format) }; let mut data = unsafe { Data::from_parts(data, len, sample_format) };
let mut data_callback = data_callback_handle.lock().unwrap(); let mut data_callback = data_callback_handle.lock().unwrap();
let callback = unimplemented!(); let callback = crate::StreamInstant::from_secs_f64(now);
let playback = unimplemented!(); let playback = crate::StreamInstant::from_secs_f64(time_at_start_of_buffer);
let timestamp = crate::OutputStreamTimestamp { callback, playback }; let timestamp = crate::OutputStreamTimestamp { callback, playback };
let info = OutputCallbackInfo { timestamp }; let info = OutputCallbackInfo { timestamp };
(data_callback.deref_mut())(&mut data, &info); (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 (self.secs as i128 * 1_000_000_000) + self.nanos as i128
} }
#[allow(dead_code)]
fn from_nanos(nanos: i64) -> Self { fn from_nanos(nanos: i64) -> Self {
let secs = nanos / 1_000_000_000; let secs = nanos / 1_000_000_000;
let subsec_nanos = nanos - secs * 1_000_000_000; let subsec_nanos = nanos - secs * 1_000_000_000;
Self::new(secs as i64, subsec_nanos as u32) Self::new(secs as i64, subsec_nanos as u32)
} }
#[allow(dead_code)]
fn from_nanos_i128(nanos: i128) -> Option<Self> { fn from_nanos_i128(nanos: i128) -> Option<Self> {
let secs = nanos / 1_000_000_000; let secs = nanos / 1_000_000_000;
if secs > std::i64::MAX as i128 || secs < std::i64::MIN as i128 { 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 { fn new(secs: i64, nanos: u32) -> Self {
StreamInstant { secs, nanos } StreamInstant { secs, nanos }
} }