removes default try_seek impl, impl try_seek for decoders + refactors decoderimpl a bit

This commit is contained in:
dvdsk 2023-10-04 12:05:03 +02:00
parent 202687b934
commit 1f3f36a4c8
No known key found for this signature in database
GPG key ID: 6CF9D20C5709A836
15 changed files with 200 additions and 156 deletions

View file

@ -13,6 +13,7 @@
use std::time::Duration;
use std::vec::IntoIter as VecIntoIter;
use crate::source::SeekNotSupported;
use crate::{Sample, Source};
/// A buffer of samples treated as a source.
@ -84,6 +85,11 @@ where
fn total_duration(&self) -> Option<Duration> {
Some(self.duration)
}
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}
impl<S> Iterator for SamplesBuffer<S>

View file

@ -4,6 +4,7 @@ use std::mem;
use std::time::Duration;
use crate::Source;
use crate::source::SeekNotSupported;
use claxon::FlacReader;
@ -79,6 +80,11 @@ where
self.samples
.map(|s| Duration::from_micros(s * 1_000_000 / self.sample_rate as u64))
}
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}
impl<R> Iterator for FlacDecoder<R>

View file

@ -9,6 +9,7 @@ use std::mem;
use std::str::FromStr;
use std::time::Duration;
use crate::source::SeekNotSupported;
use crate::Source;
#[cfg(feature = "symphonia")]
@ -57,6 +58,129 @@ where
None(::std::marker::PhantomData<R>),
}
impl<R: Read + Seek> DecoderImpl<R> {
#[inline]
fn next(&mut self) -> Option<i16> {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.next(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.next(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.next(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.next(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.next(),
DecoderImpl::None(_) => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.size_hint(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.size_hint(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.size_hint(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.size_hint(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.size_hint(),
DecoderImpl::None(_) => (0, None),
}
}
#[inline]
fn current_frame_len(&self) -> Option<usize> {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.current_frame_len(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.current_frame_len(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.current_frame_len(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.current_frame_len(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.current_frame_len(),
DecoderImpl::None(_) => Some(0),
}
}
#[inline]
fn channels(&self) -> u16 {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.channels(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.channels(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.channels(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.channels(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.channels(),
DecoderImpl::None(_) => 0,
}
}
#[inline]
fn sample_rate(&self) -> u32 {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.sample_rate(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.sample_rate(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.sample_rate(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.sample_rate(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.sample_rate(),
DecoderImpl::None(_) => 1,
}
}
#[inline]
fn total_duration(&self) -> Option<Duration> {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.total_duration(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.total_duration(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.total_duration(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.total_duration(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.total_duration(),
DecoderImpl::None(_) => Some(Duration::default()),
}
}
#[inline]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekNotSupported> {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.try_seek(pos),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.try_seek(pos),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.try_seek(pos),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.try_seek(pos),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.try_seek(pos),
DecoderImpl::None(_) => Err(SeekNotSupported {
source: "DecoderImpl::None",
}),
}
}
}
impl<R> Decoder<R>
where
R: Read + Seek + Send + Sync + 'static,
@ -261,36 +385,12 @@ where
#[inline]
fn next(&mut self) -> Option<i16> {
match &mut self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.next(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.next(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.next(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.next(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.next(),
DecoderImpl::None(_) => None,
}
self.0.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.size_hint(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.size_hint(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.size_hint(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.size_hint(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.size_hint(),
DecoderImpl::None(_) => (0, None),
}
self.0.size_hint()
}
}
@ -300,70 +400,26 @@ where
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.current_frame_len(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.current_frame_len(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.current_frame_len(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.current_frame_len(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.current_frame_len(),
DecoderImpl::None(_) => Some(0),
}
self.0.current_frame_len()
}
#[inline]
fn channels(&self) -> u16 {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.channels(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.channels(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.channels(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.channels(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.channels(),
DecoderImpl::None(_) => 0,
}
self.0.channels()
}
#[inline]
fn sample_rate(&self) -> u32 {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.sample_rate(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.sample_rate(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.sample_rate(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.sample_rate(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.sample_rate(),
DecoderImpl::None(_) => 1,
}
self.0.sample_rate()
}
#[inline]
fn total_duration(&self) -> Option<Duration> {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.total_duration(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.total_duration(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.total_duration(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.total_duration(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.total_duration(),
DecoderImpl::None(_) => Some(Duration::default()),
}
self.0.total_duration()
}
#[inline]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekNotSupported> {
self.0.try_seek(pos)
}
}
@ -375,19 +431,7 @@ where
#[inline]
fn next(&mut self) -> Option<i16> {
if let Some(sample) = match &mut self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.next(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.next(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.next(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.next(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.next(),
DecoderImpl::None(_) => None,
} {
if let Some(sample) = self.0.next() {
Some(sample)
} else {
let decoder = mem::replace(&mut self.0, DecoderImpl::None(Default::default()));
@ -444,19 +488,7 @@ where
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => (source.size_hint().0, None),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => (source.size_hint().0, None),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => (source.size_hint().0, None),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => (source.size_hint().0, None),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => (source.size_hint().0, None),
DecoderImpl::None(_) => (0, None),
}
self.0.size_hint()
}
}
@ -466,59 +498,27 @@ where
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.current_frame_len(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.current_frame_len(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.current_frame_len(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.current_frame_len(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.current_frame_len(),
DecoderImpl::None(_) => Some(0),
}
self.0.current_frame_len()
}
#[inline]
fn channels(&self) -> u16 {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.channels(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.channels(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.channels(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.channels(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.channels(),
DecoderImpl::None(_) => 0,
}
self.0.channels()
}
#[inline]
fn sample_rate(&self) -> u32 {
match &self.0 {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.sample_rate(),
#[cfg(all(feature = "vorbis", not(feature = "symphonia-vorbis")))]
DecoderImpl::Vorbis(source) => source.sample_rate(),
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
DecoderImpl::Flac(source) => source.sample_rate(),
#[cfg(all(feature = "minimp3", not(feature = "symphonia-mp3")))]
DecoderImpl::Mp3(source) => source.sample_rate(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.sample_rate(),
DecoderImpl::None(_) => 1,
}
self.0.sample_rate()
}
#[inline]
fn total_duration(&self) -> Option<Duration> {
None
}
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekNotSupported> {
self.0.try_seek(pos)
}
}
/// Error that can happen when creating a decoder.

View file

@ -71,7 +71,7 @@ where
let pos = (pos.as_secs_f32() * self.sample_rate() as f32) as u64;
// do not trigger a sample_rate, channels and frame len update
// as the seek only takes effect after the current frame is done
self.decoder.seek_samples(pos).is_ok();
let ignore_err = self.decoder.seek_samples(pos);
Ok(())
}
}

View file

@ -3,6 +3,7 @@ use std::time::Duration;
use std::vec;
use crate::Source;
use crate::source::SeekNotSupported;
use lewton::inside_ogg::OggStreamReader;
@ -73,6 +74,11 @@ where
fn total_duration(&self) -> Option<Duration> {
None
}
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}
impl<R> Iterator for VorbisDecoder<R>

View file

@ -2,6 +2,7 @@ use std::io::{Read, Seek, SeekFrom};
use std::time::Duration;
use crate::Source;
use crate::source::SeekNotSupported;
use hound::{SampleFormat, WavReader};
@ -128,6 +129,11 @@ where
fn total_duration(&self) -> Option<Duration> {
Some(self.total_duration)
}
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}
impl<R> Iterator for WavDecoder<R>

View file

@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::source::{Source, UniformSourceIterator};
use crate::source::{SeekNotSupported, Source, UniformSourceIterator};
use crate::Sample;
/// Builds a new mixer.
@ -106,6 +106,16 @@ where
fn total_duration(&self) -> Option<Duration> {
None
}
#[inline]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekNotSupported> {
todo!("needs Source::can_seek")
// if self.current_sources.iter().all(Source::can_seek) {
// for source in self.current_sources {
// source.try_seek().expect("we just verified they can")
// }
// }
}
}
impl<S> Iterator for DynamicMixer<S>

View file

@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::source::{Empty, Source, Zero};
use crate::source::{Empty, Source, Zero, SeekNotSupported};
use crate::Sample;
#[cfg(feature = "crossbeam-channel")]
@ -169,6 +169,12 @@ where
fn total_duration(&self) -> Option<Duration> {
None
}
#[inline]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekNotSupported> {
self.current.try_seek(pos)
}
}
impl<S> Iterator for SourcesQueueOutput<S>

View file

@ -244,7 +244,7 @@ where
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported)
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}

View file

@ -58,6 +58,6 @@ where
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported)
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}

View file

@ -57,6 +57,6 @@ where
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported)
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}

View file

@ -359,13 +359,11 @@ where
///
/// Try to seek to a pos, returns [`SeekNotSupported`] if seeking is not
/// supported by the current source.
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported)
}
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SeekNotSupported;
pub struct SeekNotSupported{ pub source: &'static str }
impl fmt::Display for SeekNotSupported {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

View file

@ -63,6 +63,6 @@ impl Source for SineWave {
// It is possible to write an implementation that skips the right
// amount of samples to get into the right phase. I do not think there
// is a use case for that however.
Err(SeekNotSupported)
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}

View file

@ -13,6 +13,7 @@
use std::slice::Iter as SliceIter;
use std::time::Duration;
use crate::source::SeekNotSupported;
use crate::{Sample, Source};
/// A buffer of samples treated as a source.
@ -84,6 +85,11 @@ where
fn total_duration(&self) -> Option<Duration> {
Some(self.duration)
}
#[inline]
fn try_seek(&mut self, _: Duration) -> Result<(), SeekNotSupported> {
Err(SeekNotSupported { source: std::any::type_name::<Self>() })
}
}
impl<S> Iterator for StaticSamplesBuffer<S>

View file

@ -11,7 +11,7 @@ fn seek_not_supported_returns_err() {
let file = std::fs::File::open("assets/music.wav").unwrap();
sink.append(rodio::Decoder::new(BufReader::new(file)).unwrap());
let res = sink.try_seek(Duration::from_secs(5));
assert_eq!(res, Err(rodio::source::SeekNotSupported));
assert_eq!(res, Err(rodio::source::SeekNotSupported { source: "test" }));
}
// mp3 decoder does support seeking