use core::num::NonZeroU32;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct SampleRate(pub NonZeroU32);
impl SampleRate {
pub const HZ_8000: SampleRate = unsafe { SampleRate(NonZeroU32::new_unchecked(8_000)) };
pub const HZ_11025: SampleRate = unsafe { SampleRate(NonZeroU32::new_unchecked(11_025)) };
pub const HZ_16000: SampleRate = unsafe { SampleRate(NonZeroU32::new_unchecked(16_000)) };
pub const HZ_22050: SampleRate = unsafe { SampleRate(NonZeroU32::new_unchecked(22_050)) };
pub const HZ_44100: SampleRate = unsafe { SampleRate(NonZeroU32::new_unchecked(44_100)) };
pub const HZ_48000: SampleRate = unsafe { SampleRate(NonZeroU32::new_unchecked(48_000)) };
#[must_use]
pub const fn new(hz: u32) -> Option<SampleRate> {
match NonZeroU32::new(hz) {
Some(n) => Some(SampleRate(n)),
None => None,
}
}
#[must_use]
pub const fn hz(self) -> u32 {
self.0.get()
}
}
#[derive(Clone, Debug)]
pub struct AudioBuffer<'a> {
pub samples: &'a [f32],
pub rate: SampleRate,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TimestampMs(pub u64);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sample_rate_constants_match_their_names() {
assert_eq!(SampleRate::HZ_8000.hz(), 8_000);
assert_eq!(SampleRate::HZ_11025.hz(), 11_025);
assert_eq!(SampleRate::HZ_16000.hz(), 16_000);
assert_eq!(SampleRate::HZ_22050.hz(), 22_050);
assert_eq!(SampleRate::HZ_44100.hz(), 44_100);
assert_eq!(SampleRate::HZ_48000.hz(), 48_000);
}
#[test]
fn sample_rate_eq() {
let a = SampleRate::HZ_44100;
let b = SampleRate::new(44_100).unwrap();
let c = SampleRate::HZ_48000;
assert_eq!(a, b);
assert_ne!(a, c);
}
#[test]
fn sample_rate_new_rejects_zero() {
assert!(SampleRate::new(0).is_none());
assert_eq!(SampleRate::new(1).unwrap().hz(), 1);
}
#[test]
fn timestamp_ord() {
let a = TimestampMs(100);
let b = TimestampMs(200);
assert!(a < b);
assert_eq!(a.cmp(&b), core::cmp::Ordering::Less);
assert_eq!(b.cmp(&a), core::cmp::Ordering::Greater);
assert_eq!(a.cmp(&a), core::cmp::Ordering::Equal);
}
#[test]
fn audio_buffer_borrow() {
let samples = alloc::vec![0.1_f32, 0.2, 0.3];
let buf = AudioBuffer {
samples: &samples,
rate: SampleRate::HZ_16000,
};
assert_eq!(buf.samples.len(), 3);
assert_eq!(buf.rate.hz(), 16_000);
assert_eq!(samples.len(), 3);
}
}