Refactored enum trait wrappers to dynamic traits
parent
7204270277
commit
c900e9b96e
|
|
@ -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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue