#![warn(clippy::missing_panics_doc)]
#![deny(trivial_numeric_casts)]
use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
pub(crate) const RENDER_QUANTUM_SIZE: usize = 128;
pub const MAX_CHANNELS: usize = 32;
mod buffer;
pub use buffer::*;
mod capacity;
pub use capacity::*;
pub mod context;
pub(crate) mod control;
pub mod media;
pub mod node;
mod events;
pub use events::Event;
mod param;
pub use param::*;
mod periodic_wave;
pub use periodic_wave::*;
pub mod render;
mod spatial;
pub use spatial::AudioListener;
mod io;
pub use io::{enumerate_devices, MediaDeviceInfo, MediaDeviceInfoKind};
mod analysis;
mod message;
#[derive(Debug)]
pub(crate) struct AtomicF32 {
inner: AtomicU32,
}
impl AtomicF32 {
pub fn new(v: f32) -> Self {
Self {
inner: AtomicU32::new(u32::from_ne_bytes(v.to_ne_bytes())),
}
}
pub fn load(&self, ordering: Ordering) -> f32 {
f32::from_ne_bytes(self.inner.load(ordering).to_ne_bytes())
}
pub fn store(&self, v: f32, ordering: Ordering) {
self.inner
.store(u32::from_ne_bytes(v.to_ne_bytes()), ordering);
}
}
#[derive(Debug)]
pub(crate) struct AtomicF64 {
inner: AtomicU64,
}
impl AtomicF64 {
pub fn new(v: f64) -> Self {
Self {
inner: AtomicU64::new(u64::from_ne_bytes(v.to_ne_bytes())),
}
}
pub fn load(&self) -> f64 {
f64::from_ne_bytes(self.inner.load(Ordering::SeqCst).to_ne_bytes())
}
pub fn store(&self, v: f64) {
self.inner
.store(u64::from_ne_bytes(v.to_ne_bytes()), Ordering::SeqCst)
}
}
#[track_caller]
#[inline(always)]
pub(crate) fn assert_valid_sample_rate(sample_rate: f32) {
if sample_rate <= 1000. {
panic!(
"NotSupportedError - Invalid sample rate: {:?}, should be greater than 1000",
sample_rate
);
}
}
#[track_caller]
#[inline(always)]
pub(crate) fn assert_valid_number_of_channels(number_of_channels: usize) {
if number_of_channels == 0 || number_of_channels > MAX_CHANNELS {
panic!(
"NotSupportedError - Invalid number of channels: {:?} is outside range [1, {:?}]",
number_of_channels, MAX_CHANNELS
);
}
}
#[track_caller]
#[inline(always)]
pub(crate) fn assert_valid_channel_number(channel_number: usize, number_of_channels: usize) {
if channel_number >= number_of_channels {
panic!(
"IndexSizeError - Invalid channel number {:?} (number of channels: {:?})",
channel_number, number_of_channels
);
}
}
#[cfg(test)]
mod tests {
use float_eq::assert_float_eq;
use super::*;
#[test]
fn test_atomic_f64() {
let f = AtomicF64::new(2.0);
assert_float_eq!(f.load(), 2.0, abs <= 0.);
f.store(3.0);
assert_float_eq!(f.load(), 3.0, abs <= 0.);
}
#[test]
#[should_panic]
fn test_invalid_sample_rate_zero() {
assert_valid_sample_rate(0.);
}
#[test]
#[should_panic]
fn test_invalid_sample_rate_subzero() {
assert_valid_sample_rate(-48000.);
}
#[test]
#[should_panic]
fn test_invalid_sample_rate_too_small() {
assert_valid_sample_rate(100.);
}
#[test]
fn test_valid_sample_rate() {
assert_valid_sample_rate(48000.);
}
#[test]
#[should_panic]
fn test_invalid_number_of_channels_min() {
assert_valid_number_of_channels(0);
}
#[test]
#[should_panic]
fn test_invalid_number_of_channels_max() {
assert_valid_number_of_channels(33);
}
#[test]
fn test_valid_number_of_channels() {
assert_valid_number_of_channels(1);
assert_valid_number_of_channels(32);
}
}