use super::*;
#[derive(Clone, Copy, Debug)]
pub(crate) struct Fps {
duration: Duration,
fps: NonZeroU32,
}
impl Fps {
pub(crate) fn duration(self) -> Duration {
self.duration
}
pub(crate) fn fps(self) -> NonZeroU32 {
self.fps
}
pub(crate) fn spf(self, format: SoundFormat) -> Result<usize> {
if !format.sample_rate.is_multiple_of(self.fps.get()) {
return Err(
error::SamplesPerFrame {
fps: self,
sample_rate: format.sample_rate,
}
.build(),
);
}
Ok(format.sample_rate.into_usize() / self.fps.get().into_usize() * format.channels.into_usize())
}
}
impl FromStr for Fps {
type Err = String;
fn from_str(s: &str) -> Result<Self, String> {
s.parse::<NonZeroU32>()
.map_err(|err| format!("failed to parse fps: {err}"))?
.try_into()
}
}
impl TryFrom<NonZeroU32> for Fps {
type Error = String;
fn try_from(fps: NonZeroU32) -> Result<Self, String> {
let duration = Duration::try_from_secs_f64(1.0 / fps.get() as f64)
.map_err(|err| format!("failed to calculate fps duration: {err}"))?;
Ok(Self { duration, fps })
}
}
impl Display for Fps {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.fps)
}
}