#[cfg(feature = "symphonia")]
mod from_file;
#[cfg(test)]
mod test;
use std::{
fmt::{Debug, Formatter},
sync::Arc,
time::Duration,
};
use ringbuf::HeapRb;
use crate::{
dsp::Frame,
sound::{Sound, SoundData},
};
use super::{handle::StaticSoundHandle, sound::StaticSound, StaticSoundSettings};
const COMMAND_BUFFER_CAPACITY: usize = 8;
#[derive(Clone, PartialEq)]
pub struct StaticSoundData {
pub sample_rate: u32,
pub frames: Arc<Vec<Frame>>,
pub settings: StaticSoundSettings,
}
impl StaticSoundData {
pub fn duration(&self) -> Duration {
Duration::from_secs_f64(self.frames.len() as f64 / self.sample_rate as f64)
}
pub fn with_settings(&self, settings: StaticSoundSettings) -> Self {
Self {
settings,
..self.clone()
}
}
pub fn with_modified_settings(
&self,
f: impl FnOnce(StaticSoundSettings) -> StaticSoundSettings,
) -> Self {
self.with_settings(f(self.settings))
}
pub(super) fn split(self) -> (StaticSound, StaticSoundHandle) {
let (command_producer, command_consumer) = HeapRb::new(COMMAND_BUFFER_CAPACITY).split();
let sound = StaticSound::new(self, command_consumer);
let shared = sound.shared();
(
sound,
StaticSoundHandle {
command_producer,
shared,
},
)
}
}
impl SoundData for StaticSoundData {
type Error = ();
type Handle = StaticSoundHandle;
#[allow(clippy::type_complexity)]
fn into_sound(self) -> Result<(Box<dyn Sound>, Self::Handle), Self::Error> {
let (sound, handle) = self.split();
Ok((Box::new(sound), handle))
}
}
impl Debug for StaticSoundData {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StaticSoundData")
.field("sample_rate", &self.sample_rate)
.field(
"frames",
&FramesDebug {
len: self.frames.len(),
},
)
.field("settings", &self.settings)
.finish()
}
}
struct FramesDebug {
len: usize,
}
impl Debug for FramesDebug {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("[{} frames]", self.len))
}
}