use rodio::Decoder;
use rodio::source::Buffered;
use rodio::source::Source;
use std::fs::File;
use std::io::BufReader;
use crate::prelude::*;
#[derive(Block)]
pub struct FileSource<O = DefaultCpuWriter<f32>>
where
O: CpuBufferWriter<Item = f32>,
{
#[output]
output: O,
src: Buffered<Decoder<BufReader<File>>>,
}
impl<O> FileSource<O>
where
O: CpuBufferWriter<Item = f32>,
{
pub fn new(file: &str) -> Self {
let file = BufReader::new(File::open(file).unwrap());
let source = Decoder::new(file).unwrap();
FileSource {
output: O::default(),
src: source.buffered(),
}
}
pub fn sample_rate(&self) -> u32 {
self.src.sample_rate()
}
pub fn channels(&self) -> u16 {
self.src.channels()
}
}
#[doc(hidden)]
impl<O> Kernel for FileSource<O>
where
O: CpuBufferWriter<Item = f32>,
{
async fn work(
&mut self,
io: &mut WorkIo,
_mio: &mut MessageOutputs,
_meta: &mut BlockMeta,
) -> Result<()> {
let out = self.output.slice();
let o_len = out.len();
let mut n = 0;
for (i, v) in self.src.by_ref().take(out.len()).enumerate() {
out[i] = v;
n += 1;
}
self.output.produce(n);
if n < o_len {
io.finished = true;
}
Ok(())
}
}