Skip to content

Commit

Permalink
Declare SampleRate and ChannelCount types inside rodio
Browse files Browse the repository at this point in the history
  • Loading branch information
PetrGlad committed Dec 25, 2024
1 parent dff4ea6 commit 8993f67
Show file tree
Hide file tree
Showing 56 changed files with 337 additions and 318 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ exclude = ["assets/**", "tests/**"]
edition = "2021"

[dependencies]
cpal = "0.15.3"
cpal = { version = "0.15.3", optional = true }
claxon = { version = "0.4.2", optional = true }
hound = { version = "3.3.1", optional = true }
lewton = { version = "0.10", optional = true }
minimp3_fixed = { version = "0.5.4", optional = true}
minimp3_fixed = { version = "0.5.4", optional = true }
symphonia = { version = "0.5.4", optional = true, default-features = false }
crossbeam-channel = { version = "0.5.8", optional = true }

Expand All @@ -25,7 +25,7 @@ atomic_float = { version = "1.1.0", optional = true }
num-rational = "0.4.2"

[features]
default = ["flac", "vorbis", "wav", "mp3"]
default = ["flac", "vorbis", "wav", "mp3", "cpal"]
tracing = ["dep:tracing"]
experimental = ["dep:atomic_float"]

Expand Down
4 changes: 2 additions & 2 deletions benches/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ impl<T: rodio::Sample> Source for TestSource<T> {
None // forever
}

fn channels(&self) -> u16 {
fn channels(&self) -> ChannelCount {
self.channels
}

fn sample_rate(&self) -> u32 {
fn sample_rate(&self) -> SampleRate {
self.sample_rate
}

Expand Down
4 changes: 2 additions & 2 deletions examples/custom_config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cpal::traits::HostTrait;
use cpal::{BufferSize, SampleFormat, SampleRate};
use cpal::{BufferSize, SampleFormat};
use rodio::source::SineWave;
use rodio::Source;
use std::error::Error;
Expand All @@ -15,7 +15,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// No need to set all parameters explicitly here,
// the defaults were set from the device's description.
.with_buffer_size(BufferSize::Fixed(256))
.with_sample_rate(SampleRate(48_000))
.with_sample_rate(48_000)
.with_sample_format(SampleFormat::F32)
// Note that the function below still tries alternative configs if the specified one fails.
// If you need to only use the exact specified configuration,
Expand Down
8 changes: 3 additions & 5 deletions examples/noise_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ fn main() -> Result<(), Box<dyn Error>> {

thread::sleep(interval_duration);

stream_handle.mixer().add(
pink(cpal::SampleRate(48000))
.amplify(0.1)
.take_duration(noise_duration),
);
stream_handle
.mixer()
.add(pink(48000).amplify(0.1).take_duration(noise_duration));
println!("Playing pink noise");

thread::sleep(interval_duration);
Expand Down
2 changes: 1 addition & 1 deletion examples/signal_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() -> Result<(), Box<dyn Error>> {

let test_signal_duration = Duration::from_millis(1000);
let interval_duration = Duration::from_millis(1500);
let sample_rate = cpal::SampleRate(48000);
let sample_rate = 48000;

println!("Playing 1000 Hz tone");
stream_handle.mixer().add(
Expand Down
19 changes: 10 additions & 9 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
//! ```
//!
use std::time::Duration;

use crate::common::{ChannelCount, SampleRate};
use crate::source::SeekError;
use crate::{Sample, Source};
use std::time::Duration;

/// A buffer of samples treated as a source.
#[derive(Debug, Clone)]
pub struct SamplesBuffer<S> {
data: Vec<S>,
pos: usize,
channels: u16,
sample_rate: u32,
channels: ChannelCount,
sample_rate: SampleRate,
duration: Duration,
}

Expand All @@ -38,7 +38,7 @@ where
/// - Panics if the length of the buffer is larger than approximately 16 billion elements.
/// This is because the calculation of the duration would overflow.
///
pub fn new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S>
pub fn new<D>(channels: ChannelCount, sample_rate: SampleRate, data: D) -> SamplesBuffer<S>
where
D: Into<Vec<S>>,
{
Expand Down Expand Up @@ -74,12 +74,12 @@ where
}

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

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

Expand Down Expand Up @@ -174,12 +174,13 @@ mod tests {
#[cfg(test)]
mod try_seek {
use super::*;
use crate::common::{ChannelCount, SampleRate};
use std::time::Duration;

#[test]
fn channel_order_stays_correct() {
const SAMPLE_RATE: u32 = 100;
const CHANNELS: u16 = 2;
const SAMPLE_RATE: SampleRate = 100;
const CHANNELS: ChannelCount = 2;
let mut buf = SamplesBuffer::new(
CHANNELS,
SAMPLE_RATE,
Expand Down
16 changes: 7 additions & 9 deletions src/conversions/channels.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::common::ChannelCount;
use cpal::Sample;

/// Iterator that converts from a certain channel count to another.
Expand All @@ -7,10 +8,10 @@ where
I: Iterator,
{
input: I,
from: cpal::ChannelCount,
to: cpal::ChannelCount,
from: ChannelCount,
to: ChannelCount,
sample_repeat: Option<I::Item>,
next_output_sample_pos: cpal::ChannelCount,
next_output_sample_pos: ChannelCount,
}

impl<I> ChannelCountConverter<I>
Expand All @@ -24,11 +25,7 @@ where
/// Panics if `from` or `to` are equal to 0.
///
#[inline]
pub fn new(
input: I,
from: cpal::ChannelCount,
to: cpal::ChannelCount,
) -> ChannelCountConverter<I> {
pub fn new(input: I, from: ChannelCount, to: ChannelCount) -> ChannelCountConverter<I> {
assert!(from >= 1);
assert!(to >= 1);

Expand Down Expand Up @@ -118,6 +115,7 @@ where
#[cfg(test)]
mod test {
use super::ChannelCountConverter;
use crate::common::ChannelCount;

#[test]
fn remove_channels() {
Expand Down Expand Up @@ -147,7 +145,7 @@ mod test {

#[test]
fn size_hint() {
fn test(input: &[i16], from: cpal::ChannelCount, to: cpal::ChannelCount) {
fn test(input: &[i16], from: ChannelCount, to: ChannelCount) {
let mut converter = ChannelCountConverter::new(input.iter().copied(), from, to);
let count = converter.clone().count();
for left_in_iter in (0..=count).rev() {
Expand Down
42 changes: 20 additions & 22 deletions src/conversions/sample_rate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::conversions::Sample;

use crate::common::{ChannelCount, SampleRate};
use num_rational::Ratio;
use std::mem;

Expand All @@ -16,7 +17,7 @@ where
/// We convert chunks of `from` samples into chunks of `to` samples.
to: u32,
/// Number of channels in the stream
channels: cpal::ChannelCount,
channels: ChannelCount,
/// One sample per channel, extracted from `input`.
current_span: Vec<I::Item>,
/// Position of `current_sample` modulo `from`.
Expand Down Expand Up @@ -51,12 +52,12 @@ where
#[inline]
pub fn new(
mut input: I,
from: cpal::SampleRate,
to: cpal::SampleRate,
num_channels: cpal::ChannelCount,
from: SampleRate,
to: SampleRate,
num_channels: ChannelCount,
) -> SampleRateConverter<I> {
let from = from.0;
let to = to.0;
let from = from;
let to = to;

assert!(num_channels >= 1);
assert!(from >= 1);
Expand Down Expand Up @@ -251,8 +252,8 @@ where
#[cfg(test)]
mod test {
use super::SampleRateConverter;
use crate::common::{ChannelCount, SampleRate};
use core::time::Duration;
use cpal::{ChannelCount, SampleRate};
use quickcheck::{quickcheck, TestResult};

quickcheck! {
Expand All @@ -264,8 +265,8 @@ mod test {
{
return TestResult::discard();
}
let from = SampleRate(from as u32);
let to = SampleRate(to as u32);
let from = from as SampleRate;
let to = to as SampleRate;

let input: Vec<u16> = Vec::new();
let output =
Expand All @@ -279,7 +280,7 @@ mod test {
/// Check that resampling to the same rate does not change the signal.
fn identity(from: u16, channels: u8, input: Vec<u16>) -> TestResult {
if channels == 0 || channels > 128 || from == 0 { return TestResult::discard(); }
let from = SampleRate(from as u32);
let from = from as SampleRate;

let output =
SampleRateConverter::new(input.clone().into_iter(), from, from, channels as ChannelCount)
Expand All @@ -295,7 +296,7 @@ mod test {
return TestResult::discard();
}

let to = SampleRate(to as u32);
let to = to as SampleRate;
let from = to * k as u32;

// Truncate the input, so it contains an integer number of spans.
Expand All @@ -321,7 +322,7 @@ mod test {
return TestResult::discard();
}

let from = SampleRate(from as u32);
let from = from as SampleRate;
let to = from * k as u32;

// Truncate the input, so it contains an integer number of spans.
Expand All @@ -345,19 +346,19 @@ mod test {
/// Check that resampling does not change the audio duration,
/// except by a negligible amount (± 1ms). Reproduces #316.
/// Ignored, pending a bug fix.
fn preserve_durations(d: Duration, freq: f32, to: u32) -> TestResult {
fn preserve_durations(d: Duration, freq: f32, to: SampleRate) -> TestResult {
if to == 0 { return TestResult::discard(); }

use crate::source::{SineWave, Source};

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

let resampled =
SampleRateConverter::new(source, from, to, 1);
let duration =
Duration::from_secs_f32(resampled.count() as f32 / to.0 as f32);
Duration::from_secs_f32(resampled.count() as f32 / to as f32);

let delta = if d < duration { duration - d } else { d - duration };
TestResult::from_bool(delta < Duration::from_millis(1))
Expand All @@ -367,8 +368,7 @@ mod test {
#[test]
fn upsample() {
let input = vec![2u16, 16, 4, 18, 6, 20, 8, 22];
let output =
SampleRateConverter::new(input.into_iter(), SampleRate(2000), SampleRate(3000), 2);
let output = SampleRateConverter::new(input.into_iter(), 2000, 3000, 2);
assert_eq!(output.len(), 12); // Test the source's Iterator::size_hint()

let output = output.collect::<Vec<_>>();
Expand All @@ -378,8 +378,7 @@ mod test {
#[test]
fn upsample2() {
let input = vec![1u16, 14];
let output =
SampleRateConverter::new(input.into_iter(), SampleRate(1000), SampleRate(7000), 1);
let output = SampleRateConverter::new(input.into_iter(), 1000, 7000, 1);
let size_estimation = output.len();
let output = output.collect::<Vec<_>>();
assert_eq!(output, [1, 2, 4, 6, 8, 10, 12, 14]);
Expand All @@ -389,8 +388,7 @@ mod test {
#[test]
fn downsample() {
let input = Vec::from_iter(0u16..17);
let output =
SampleRateConverter::new(input.into_iter(), SampleRate(12000), SampleRate(2400), 1);
let output = SampleRateConverter::new(input.into_iter(), 12000, 2400, 1);
let size_estimation = output.len();
let output = output.collect::<Vec<_>>();
assert_eq!(output, [0, 5, 10, 15]);
Expand Down
11 changes: 6 additions & 5 deletions src/decoder/flac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::time::Duration;
use crate::source::SeekError;
use crate::Source;

use crate::common::{ChannelCount, SampleRate};
use claxon::FlacReader;

/// Decoder for the Flac format.
Expand All @@ -18,8 +19,8 @@ where
current_block_channel_len: usize,
current_block_off: usize,
bits_per_sample: u32,
sample_rate: u32,
channels: u16,
sample_rate: SampleRate,
channels: ChannelCount,
samples: Option<u64>,
}

Expand All @@ -45,7 +46,7 @@ where
current_block_off: 0,
bits_per_sample: spec.bits_per_sample,
sample_rate: spec.sample_rate,
channels: spec.channels as u16,
channels: spec.channels as ChannelCount,
samples: spec.samples,
})
}
Expand All @@ -64,12 +65,12 @@ where
}

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

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

Expand Down
Loading

0 comments on commit 8993f67

Please sign in to comment.