use kira::sound::SoundData;
use ringbuf::RingBuffer;
use crate::{StreamingSoundHandle, StreamingSoundSettings};
use super::{
decoder::Decoder,
sound::{decode_scheduler::DecodeScheduler, StreamingSound},
};
const COMMAND_BUFFER_CAPACITY: usize = 8;
const ERROR_BUFFER_CAPACITY: usize = 8;
pub struct StreamingSoundData<Error: Send + 'static> {
pub(crate) decoder: Box<dyn Decoder<Error = Error>>,
pub settings: StreamingSoundSettings,
}
impl<Error: Send + 'static> StreamingSoundData<Error> {
pub(crate) fn split(
self,
) -> Result<
(
StreamingSound,
StreamingSoundHandle<Error>,
DecodeScheduler<Error>,
),
Error,
> {
let (command_producer, command_consumer) = RingBuffer::new(COMMAND_BUFFER_CAPACITY).split();
let (error_producer, error_consumer) = RingBuffer::new(ERROR_BUFFER_CAPACITY).split();
let sample_rate = self.decoder.sample_rate();
let (scheduler, scheduler_controller) =
DecodeScheduler::new(self.decoder, self.settings, error_producer)?;
let sound = StreamingSound::new(
command_consumer,
scheduler_controller,
self.settings,
sample_rate,
&scheduler,
);
let handle = StreamingSoundHandle {
shared: sound.shared(),
command_producer,
error_consumer,
};
Ok((sound, handle, scheduler))
}
}
impl<Error: Send + 'static> SoundData for StreamingSoundData<Error> {
type Error = Error;
type Handle = StreamingSoundHandle<Error>;
#[allow(clippy::type_complexity)]
fn into_sound(self) -> Result<(Box<dyn kira::sound::Sound>, Self::Handle), Self::Error> {
let (sound, handle, scheduler) = self.split()?;
scheduler.start();
Ok((Box::new(sound), handle))
}
}