WIP Begin work on the timestamp and `StreamInstant` APIs

This commit is contained in:
mitchmindtree 2020-04-16 19:06:47 +02:00
parent f032557fb4
commit 4cb50663d8
1 changed files with 105 additions and 4 deletions

View File

@ -158,6 +158,7 @@ pub use platform::{
SupportedInputConfigs, SupportedOutputConfigs, ALL_HOSTS, SupportedInputConfigs, SupportedOutputConfigs, ALL_HOSTS,
}; };
pub use samples_formats::{Sample, SampleFormat}; pub use samples_formats::{Sample, SampleFormat};
use std::time::Duration;
mod error; mod error;
mod host; mod host;
@ -220,13 +221,53 @@ pub struct Data {
sample_format: SampleFormat, sample_format: SampleFormat,
} }
/// Information relevant to a single call to the user's output stream data callback. /// A monotonic time instance associated with a stream, retrieved from either:
#[derive(Debug, Clone, PartialEq)] ///
pub struct OutputCallbackInfo {} /// 1. A timestamp provided to the stream's underlying audio data callback or
/// 2. The same time source used to generate timestamps for a stream's underlying audio data
/// callback.
///
/// **StreamInstant** represents a duration since some unspecified origin occurring either before
/// or equal to the moment the stream from which it was created begins.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct StreamInstant {
secs: u64,
nanos: u32,
}
/// A timestamp associated with a call to an input stream's data callback.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub struct InputStreamTimestamp {
/// The instant the stream's data callback was invoked.
pub callback: StreamInstant,
/// The instant that data was captured from the device.
///
/// E.g. The instant data was read from an ADC.
pub capture: StreamInstant,
}
/// A timestamp associated with a call to an output stream's data callback.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub struct OutputStreamTimestamp {
/// The instant the stream's data callback was invoked.
pub callback: StreamInstant,
/// The predicted instant that data written will be delivered to the device for playback.
///
/// E.g. The instant data will be played by a DAC.
pub playback: StreamInstant,
}
/// Information relevant to a single call to the user's input stream data callback. /// Information relevant to a single call to the user's input stream data callback.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct InputCallbackInfo {} pub struct InputCallbackInfo {
timestamp: InputStreamTimestamp,
}
/// Information relevant to a single call to the user's output stream data callback.
#[derive(Debug, Clone, PartialEq)]
pub struct OutputCallbackInfo {
timestamp: OutputStreamTimestamp,
}
impl SupportedStreamConfig { impl SupportedStreamConfig {
pub fn channels(&self) -> ChannelCount { pub fn channels(&self) -> ChannelCount {
@ -249,6 +290,66 @@ impl SupportedStreamConfig {
} }
} }
impl StreamInstant {
/// The amount of time elapsed from another instant to this one.
///
/// Returns `None` if `earlier` is later than self.
pub fn duration_since(&self, earlier: &Self) -> Option<Duration> {
if self < earlier {
None
} else {
Some(self.as_duration() - earlier.as_duration())
}
}
/// Returns the instant in time after the given duration has passed.
///
/// Returns `None` if the resulting instant would exceed the bounds of the underlying data
/// structure.
pub fn add(&self, duration: Duration) -> Option<Self> {
self.as_duration()
.checked_add(duration)
.map(Self::from_duration)
}
/// Returns the instant in time one `duration` ago.
///
/// Returns `None` if the resulting instant would underflow. As a result, it is important to
/// consider that on some platforms the `StreamInstant` may begin at `0` from the moment the
/// source stream is created.
pub fn sub(&self, duration: Duration) -> Option<Self> {
self.as_duration()
.checked_sub(duration)
.map(Self::from_duration)
}
fn new(secs: u64, nanos: u32) -> Self {
StreamInstant { secs, nanos }
}
fn as_duration(&self) -> Duration {
Duration::new(self.secs, self.nanos)
}
fn from_duration(d: Duration) -> Self {
Self::new(d.as_secs(), d.subsec_nanos())
}
}
impl InputCallbackInfo {
/// The timestamp associated with the call to an input stream's data callback.
pub fn timestamp(&self) -> InputStreamTimestamp {
self.timestamp
}
}
impl OutputCallbackInfo {
/// The timestamp associated with the call to an output stream's data callback.
pub fn timestamp(&self) -> OutputStreamTimestamp {
self.timestamp
}
}
impl Data { impl Data {
// Internal constructor for host implementations to use. // Internal constructor for host implementations to use.
// //