Refactored enum trait wrappers to dynamic traits

master
hheik 2024-03-10 07:17:34 +02:00
parent 7204270277
commit c900e9b96e
2 changed files with 89 additions and 67 deletions

View File

@ -1,96 +1,72 @@
// Implement decoders missing from rodio. // Implement decoders missing from rodio.
// At the moment this means opus, mod and xm. // At the moment this means:
// - Opus (Ogg, WebM)
// - Mod
// - XM
use std::io::{Read, Seek}; use std::io::{Read, Seek};
pub mod opus; mod opus;
pub enum SourceImpl<R> pub struct Decoder;
where
R: Read + Seek,
{
Rodio(rodio::Decoder<R>),
// Custom(Decoder<R>),
}
impl<R> Iterator for SourceImpl<R> impl Decoder {
where pub fn new<R>(mut data: R) -> Result<Box<dyn DecoderImpl<R, Item = i16>>, ()>
R: Read + Seek, where
{ R: Read + Seek + Send + Sync + 'static,
type Item = i16; {
let start_position = data.stream_position().unwrap();
#[inline] match opus::OpusDecoder::new(&mut data) {
fn next(&mut self) -> Option<Self::Item> { Ok(source) => return Ok(Box::new(source)),
match self { Err(err) => {
Self::Rodio(source) => source.next(), eprintln!("Custom decode error: {err:?}");
} }
};
data.seek(std::io::SeekFrom::Start(start_position)).unwrap();
match rodio::Decoder::new(data) {
Ok(source) => return Ok(Box::new(source)),
Err(err) => {
eprintln!("Rodio decode error: {err:?}");
}
};
Err(())
} }
} }
impl<R> rodio::Source for SourceImpl<R> pub trait DecoderImpl<R>: rodio::Source + Send + Sync + 'static
where
R: Read + Seek,
<Self as Iterator>::Item: rodio::Sample,
{
}
impl<R> rodio::Source for Box<dyn DecoderImpl<R, Item = i16>>
where where
R: Read + Seek, R: Read + Seek,
{ {
#[inline] #[inline]
fn current_frame_len(&self) -> Option<usize> { fn current_frame_len(&self) -> Option<usize> {
match self { self.as_ref().current_frame_len()
Self::Rodio(source) => source.current_frame_len(),
}
} }
#[inline] #[inline]
fn channels(&self) -> u16 { fn channels(&self) -> u16 {
match self { self.as_ref().channels()
Self::Rodio(source) => source.channels(),
}
} }
#[inline] #[inline]
fn sample_rate(&self) -> u32 { fn sample_rate(&self) -> u32 {
match self { self.as_ref().sample_rate()
Self::Rodio(source) => source.sample_rate(),
}
} }
#[inline] #[inline]
fn total_duration(&self) -> Option<std::time::Duration> { fn total_duration(&self) -> Option<std::time::Duration> {
match self { self.as_ref().total_duration()
Self::Rodio(source) => source.total_duration(),
}
} }
} }
pub enum Decoder<R> impl<R> DecoderImpl<R> for rodio::Decoder<R> where R: Read + Seek + Send + Sync + 'static {}
where
R: Read + Seek,
{
Opus(opus::OpusDecoder<R>),
}
impl<R> Decoder<R>
where
R: Read + Seek,
{
pub fn new(data: R) -> Result<SourceImpl<R>, ()>
where
R: Read + Seek + Send + Sync + 'static,
{
match rodio::Decoder::new(data) {
Ok(source) => return Ok(SourceImpl::Rodio(source)),
Err(err) => {
eprintln!(
"Rodio decode error:\n\terror: {err:?}\n\tcontinuing with custom decoder"
);
}
};
// match Decoder::new(data) {
// Ok(source) => return Ok(SourceImpl::Custom(source)),
// Err(err) => {
// eprintln!("Custom decode error:\n\terror: {err:?}\n\tPlayback failed");
// }
// }
Err(())
}
}

View File

@ -3,10 +3,56 @@ use std::{
marker::PhantomData, marker::PhantomData,
}; };
/// Not implemented
pub struct OpusDecoder<R> pub struct OpusDecoder<R>
where where
R: Read + Seek, R: Read + Seek,
{ {
_data: PhantomData<R>, _data: PhantomData<R>,
} }
impl<R> super::DecoderImpl<R> for OpusDecoder<R> where R: Read + Seek + Send + Sync + 'static {}
impl<R> OpusDecoder<R>
where
R: Read + Seek + Send + Sync + 'static,
{
pub fn new(data: &mut R) -> Result<Self, ()> {
Err(())
}
}
impl<R> Iterator for OpusDecoder<R>
where
R: Read + Seek,
{
type Item = i16;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
impl<R> rodio::Source for OpusDecoder<R>
where
R: Read + Seek,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
todo!()
}
#[inline]
fn channels(&self) -> u16 {
todo!()
}
#[inline]
fn sample_rate(&self) -> u32 {
todo!()
}
#[inline]
fn total_duration(&self) -> Option<std::time::Duration> {
todo!()
}
}