Skip to content

Commit

Permalink
See what happens if channels and sample_rate are options.
Browse files Browse the repository at this point in the history
This is a major refactor touching all the parts.
The idea behind it is that for the exceptional case of `Empty` we can supply None to either and otherwise we either have supplied values or some "sane" defaults available to use
  • Loading branch information
DivineGod committed Dec 5, 2024
1 parent ccfbeb6 commit 39434d0
Show file tree
Hide file tree
Showing 46 changed files with 227 additions and 233 deletions.
4 changes: 2 additions & 2 deletions benches/resampler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn no_resampling(bencher: Bencher) {
(source.channels(), source.sample_rate(), source)
})
.bench_values(|(channels, sample_rate, source)| {
UniformSourceIterator::<_, i16>::new(source, channels, sample_rate)
UniformSourceIterator::<_, i16>::new(source, channels.unwrap(), sample_rate.unwrap())
.for_each(divan::black_box_drop)
})
}
Expand All @@ -36,7 +36,7 @@ fn resample_to(bencher: Bencher, target_sample_rate: u32) {
(source.channels(), source)
})
.bench_values(|(channels, source)| {
UniformSourceIterator::<_, i16>::new(source, channels, target_sample_rate)
UniformSourceIterator::<_, i16>::new(source, channels.unwrap(), target_sample_rate)
.for_each(divan::black_box_drop)
})
}
12 changes: 6 additions & 6 deletions benches/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ impl<T: rodio::Sample> Source for TestSource<T> {
None // forever
}

fn channels(&self) -> u16 {
self.channels
fn channels(&self) -> Option<u16> {
Some(self.channels)
}

fn sample_rate(&self) -> u32 {
self.sample_rate
fn sample_rate(&self) -> Option<u32> {
Some(self.sample_rate)
}

fn total_duration(&self) -> Option<Duration> {
Expand All @@ -54,8 +54,8 @@ impl TestSource<i16> {
.take_duration(duration);

TestSource {
channels: sound.channels(),
sample_rate: sound.sample_rate(),
channels: sound.channels().unwrap(),
sample_rate: sound.sample_rate().unwrap(),
total_duration: duration,
samples: sound.into_iter().collect::<Vec<_>>().into_iter(),
}
Expand Down
16 changes: 9 additions & 7 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ where
}

#[inline]
fn channels(&self) -> u16 {
self.channels
fn channels(&self) -> Option<u16> {
Some(self.channels)
}

#[inline]
fn sample_rate(&self) -> u32 {
self.sample_rate
fn sample_rate(&self) -> Option<u32> {
Some(self.sample_rate)
}

#[inline]
Expand All @@ -95,14 +95,16 @@ where
/// This jumps in memory till the sample for `pos`.
#[inline]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
let curr_channel = self.pos % self.channels() as usize;
let new_pos = pos.as_secs_f32() * self.sample_rate() as f32 * self.channels() as f32;
let curr_channel = self.pos % self.channels().unwrap() as usize;
let new_pos = pos.as_secs_f32()
* self.sample_rate().unwrap() as f32
* self.channels().unwrap() as f32;
// saturate pos at the end of the source
let new_pos = new_pos as usize;
let new_pos = new_pos.min(self.data.len());

// make sure the next sample is for the right channel
let new_pos = new_pos.next_multiple_of(self.channels() as usize);
let new_pos = new_pos.next_multiple_of(self.channels().unwrap() as usize);
let new_pos = new_pos - curr_channel;

self.pos = new_pos;
Expand Down
18 changes: 12 additions & 6 deletions src/conversions/channels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ where
to: cpal::ChannelCount,
) -> ChannelCountConverter<I> {
assert!(to >= 1);
let from = match from {
0 => to,
n => n,
};
assert!(from >= 1);

ChannelCountConverter {
input,
Expand Down Expand Up @@ -183,9 +180,18 @@ mod test {
}

#[test]
#[should_panic]
fn zero_input() {
let input = vec![1u16, 2, 3, 4, 5, 6];
let output = ChannelCountConverter::new(input.into_iter(), 0, 3);
assert_eq!(output.len(), 6);
// Panics because from is 0
let _output = ChannelCountConverter::new(input.into_iter(), 0, 3);
}

#[test]
#[should_panic]
fn zero_output() {
let input = vec![1u16, 2, 3, 4, 5, 6];
// Panics because to is 0
let _output = ChannelCountConverter::new(input.into_iter(), 3, 0);
}
}
2 changes: 1 addition & 1 deletion src/conversions/sample_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ mod test {

let to = SampleRate(to);
let source = SineWave::new(freq).take_duration(d);
let from = SampleRate(source.sample_rate());
let from = SampleRate(source.sample_rate().unwrap());

let resampled =
SampleRateConverter::new(source, from, to, 1);
Expand Down
8 changes: 4 additions & 4 deletions src/decoder/flac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ where
}

#[inline]
fn channels(&self) -> u16 {
self.channels
fn channels(&self) -> Option<u16> {
Some(self.channels)
}

#[inline]
fn sample_rate(&self) -> u32 {
self.sample_rate
fn sample_rate(&self) -> Option<u32> {
Some(self.sample_rate)
}

#[inline]
Expand Down
16 changes: 8 additions & 8 deletions src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
}

#[inline]
fn channels(&self) -> u16 {
fn channels(&self) -> Option<u16> {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.channels(),
Expand All @@ -130,12 +130,12 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.channels(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.channels(),
DecoderImpl::None(_) => 0,
DecoderImpl::None(_) => None, // FIX-ME? I changed this from `0` to `None` instead of `Some(0)`
}
}

#[inline]
fn sample_rate(&self) -> u32 {
fn sample_rate(&self) -> Option<u32> {
match self {
#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))]
DecoderImpl::Wav(source) => source.sample_rate(),
Expand All @@ -147,7 +147,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.sample_rate(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source) => source.sample_rate(),
DecoderImpl::None(_) => 1,
DecoderImpl::None(_) => Some(1),
}
}

Expand Down Expand Up @@ -418,11 +418,11 @@ where
}

#[inline]
fn channels(&self) -> u16 {
fn channels(&self) -> Option<u16> {
self.0.channels()
}

fn sample_rate(&self) -> u32 {
fn sample_rate(&self) -> Option<u32> {
self.0.sample_rate()
}

Expand Down Expand Up @@ -516,12 +516,12 @@ where
}

#[inline]
fn channels(&self) -> u16 {
fn channels(&self) -> Option<u16> {
self.0.channels()
}

#[inline]
fn sample_rate(&self) -> u32 {
fn sample_rate(&self) -> Option<u32> {
self.0.sample_rate()
}

Expand Down
12 changes: 6 additions & 6 deletions src/decoder/symphonia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ impl Source for SymphoniaDecoder {
}

#[inline]
fn channels(&self) -> u16 {
self.spec.channels.count() as u16
fn channels(&self) -> Option<u16> {
Some(self.spec.channels.count() as u16)
}

#[inline]
fn sample_rate(&self) -> u32 {
self.spec.rate
fn sample_rate(&self) -> Option<u32> {
Some(self.spec.rate)
}

#[inline]
Expand All @@ -188,7 +188,7 @@ impl Source for SymphoniaDecoder {
};

// make sure the next sample is for the right channel
let to_skip = self.current_frame_offset % self.channels() as usize;
let to_skip = self.current_frame_offset % self.channels().unwrap() as usize;

let seek_res = self
.format
Expand Down Expand Up @@ -285,7 +285,7 @@ impl SymphoniaDecoder {
let decoded = decoded.map_err(SeekError::Decoding)?;
decoded.spec().clone_into(&mut self.spec);
self.buffer = SymphoniaDecoder::get_buffer(decoded, &self.spec);
self.current_frame_offset = samples_to_pass as usize * self.channels() as usize;
self.current_frame_offset = samples_to_pass as usize * self.channels().unwrap() as usize;
Ok(())
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/decoder/vorbis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ where
}

#[inline]
fn channels(&self) -> u16 {
self.stream_reader.ident_hdr.audio_channels as u16
fn channels(&self) -> Option<u16> {
Some(self.stream_reader.ident_hdr.audio_channels as u16)
}

#[inline]
fn sample_rate(&self) -> u32 {
self.stream_reader.ident_hdr.audio_sample_rate
fn sample_rate(&self) -> Option<u32> {
Some(self.stream_reader.ident_hdr.audio_sample_rate)
}

#[inline]
Expand Down
14 changes: 7 additions & 7 deletions src/decoder/wav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ where
}

#[inline]
fn channels(&self) -> u16 {
self.channels
fn channels(&self) -> Option<u16> {
Some(self.channels)
}

#[inline]
fn sample_rate(&self) -> u32 {
self.sample_rate
fn sample_rate(&self) -> Option<u32> {
Some(self.sample_rate)
}

#[inline]
Expand All @@ -133,18 +133,18 @@ where
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
let file_len = self.reader.reader.duration();

let new_pos = pos.as_secs_f32() * self.sample_rate() as f32;
let new_pos = pos.as_secs_f32() * self.sample_rate as f32;
let new_pos = new_pos as u32;
let new_pos = new_pos.min(file_len); // saturate pos at the end of the source

// make sure the next sample is for the right channel
let to_skip = self.reader.samples_read % self.channels() as u32;
let to_skip = self.reader.samples_read % self.channels as u32;

self.reader
.reader
.seek(new_pos)
.map_err(SeekError::HoundDecoder)?;
self.reader.samples_read = new_pos * self.channels() as u32;
self.reader.samples_read = new_pos * self.channels as u32;

for _ in 0..to_skip {
self.next();
Expand Down
30 changes: 15 additions & 15 deletions src/mixer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ where
}

#[inline]
fn channels(&self) -> u16 {
self.input.channels
fn channels(&self) -> Option<u16> {
Some(self.input.channels)
}

#[inline]
fn sample_rate(&self) -> u32 {
self.input.sample_rate
fn sample_rate(&self) -> Option<u32> {
Some(self.input.sample_rate)
}

#[inline]
Expand All @@ -113,21 +113,21 @@ where
// uncomment when #510 is implemented (query position of playback)

// let mut org_positions = Vec::with_capacity(self.current_sources.len());
// let mut encounterd_err = None;
// let mut encountered_err = None;
//
// for source in &mut self.current_sources {
// let pos = /* source.playback_pos() */ todo!();
// if let Err(e) = source.try_seek(pos) {
// encounterd_err = Some(e);
// encountered_err = Some(e);
// break;
// } else {
// // store pos in case we need to roll back
// org_positions.push(pos);
// }
// }
//
// if let Some(e) = encounterd_err {
// // rollback seeks that happend before err
// if let Some(e) = encountered_err {
// // rollback seeks that happened before err
// for (pos, source) in org_positions
// .into_iter()
// .zip(self.current_sources.iter_mut())
Expand Down Expand Up @@ -182,7 +182,7 @@ where
let mut pending = self.input.pending_sources.lock().unwrap(); // TODO: relax ordering?

for source in pending.drain(..) {
let in_step = self.sample_count % source.channels() as usize == 0;
let in_step = self.sample_count % source.channels().unwrap() as usize == 0;

if in_step {
self.current_sources.push(source);
Expand Down Expand Up @@ -224,8 +224,8 @@ mod tests {
tx.add(SamplesBuffer::new(1, 48000, vec![10i16, -10, 10, -10]));
tx.add(SamplesBuffer::new(1, 48000, vec![5i16, 5, 5, 5]));

assert_eq!(rx.channels(), 1);
assert_eq!(rx.sample_rate(), 48000);
assert_eq!(rx.channels(), Some(1));
assert_eq!(rx.sample_rate(), Some(48000));
assert_eq!(rx.next(), Some(15));
assert_eq!(rx.next(), Some(-5));
assert_eq!(rx.next(), Some(15));
Expand All @@ -240,8 +240,8 @@ mod tests {
tx.add(SamplesBuffer::new(1, 48000, vec![10i16, -10, 10, -10]));
tx.add(SamplesBuffer::new(1, 48000, vec![5i16, 5, 5, 5]));

assert_eq!(rx.channels(), 2);
assert_eq!(rx.sample_rate(), 48000);
assert_eq!(rx.channels(), Some(2));
assert_eq!(rx.sample_rate(), Some(48000));
assert_eq!(rx.next(), Some(15));
assert_eq!(rx.next(), Some(15));
assert_eq!(rx.next(), Some(-5));
Expand All @@ -260,8 +260,8 @@ mod tests {
tx.add(SamplesBuffer::new(1, 48000, vec![10i16, -10, 10, -10]));
tx.add(SamplesBuffer::new(1, 48000, vec![5i16, 5, 5, 5]));

assert_eq!(rx.channels(), 1);
assert_eq!(rx.sample_rate(), 96000);
assert_eq!(rx.channels(), Some(1));
assert_eq!(rx.sample_rate(), Some(96000));
assert_eq!(rx.next(), Some(15));
assert_eq!(rx.next(), Some(5));
assert_eq!(rx.next(), Some(-5));
Expand Down
Loading

0 comments on commit 39434d0

Please sign in to comment.