Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- All sources now implement `ExactSizeIterator` when their inner source does.
- All sources now implement `Iterator::size_hint()`.
- `Chirp` now implements `try_seek`.
- Added `DEFAULT_SAMPLE_RATE` set to match `cpal::SAMPLE_RATE_48K`.

### Changed

Expand All @@ -25,6 +26,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ensured decoders to always return complete frames, as well as `TakeDuration` when expired.
- Breaking: `Zero::new_samples()` now returns `Result<Self, ZeroError>` requiring a frame-aligned number of samples.
- Improved queue, buffer, mixer and sample rate conversion performance.
- Default sample rate changed from 44.1 kHz to 48 kHz consistently.
- `open_sink_or_fallback` now tries 48 kHz and 44.1 kHz before the device's maximum sample rate.

### Removed

- Breaking: Removed `stream::supported_output_configs`. Use `cpal::Device::supported_output_configs`.

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The list below only contains required code changes. For a complete list of
changes and new features, see [CHANGELOG.md](CHANGELOG.md).

# rodio 0.22 to current github version
- `stream::supported_output_configs` is removed. To pick a non-default device config,
call `device.supported_output_configs()` directly and pass your chosen
`SupportedStreamConfig` to `DeviceSinkBuilder::with_supported_config`.
- `Done` now calls a callback instead of decrementing an `Arc<AtomicUsize>`.
- To retain old behavior replace the `Arc<AtomicUsize>` argument in `Done::new` with
`move |_| { number.fetch_sub(1, std::sync::atomic::Ordering::Relaxed) }`.
Expand Down
5 changes: 5 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use std::fmt::{Debug, Display};
use std::num::NonZero;

use crate::math::nz;

/// Sample rate (a frame rate or samples per second per channel).
pub type SampleRate = NonZero<u32>;

/// The default sample rate used by rodio for generators and device sinks.
pub const DEFAULT_SAMPLE_RATE: SampleRate = nz!(48_000);

/// Number of channels in a stream. Can never be Zero
pub type ChannelCount = NonZero<u16>;

Expand Down
2 changes: 1 addition & 1 deletion src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ where
fn sample_rate(&self) -> SampleRate {
self.inner
.as_ref()
.map_or(nz!(44100), |inner| inner.sample_rate())
.map_or(crate::DEFAULT_SAMPLE_RATE, |inner| inner.sample_rate())
}

/// Returns the total duration of this audio source.
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ pub mod queue;
pub mod source;
pub mod static_buffer;

pub use crate::common::{BitDepth, ChannelCount, Float, Sample, SampleRate};
pub use crate::common::{BitDepth, ChannelCount, Float, Sample, SampleRate, DEFAULT_SAMPLE_RATE};
pub use crate::decoder::Decoder;
#[cfg(feature = "experimental")]
pub use crate::fixed_source::FixedSource;
Expand Down
2 changes: 1 addition & 1 deletion src/microphone/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl Default for InputConfig {
fn default() -> Self {
Self {
channel_count: nz!(1),
sample_rate: nz!(44_100),
sample_rate: crate::DEFAULT_SAMPLE_RATE,
buffer_size: cpal::BufferSize::Default,
sample_format: cpal::SampleFormat::F32,
}
Expand Down
4 changes: 2 additions & 2 deletions src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,8 @@ mod tests {
);
assert_eq!(
rx.sample_rate(),
nz!(48000),
"Initial sample rate should be 48000 (keep_alive={keep_alive})"
crate::DEFAULT_SAMPLE_RATE,
"Initial sample rate should be DEFAULT_SAMPLE_RATE (keep_alive={keep_alive})"
);

tx.append(SamplesBuffer::new(
Expand Down
2 changes: 1 addition & 1 deletion src/source/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Source for Empty {

#[inline]
fn sample_rate(&self) -> SampleRate {
nz!(48000)
crate::DEFAULT_SAMPLE_RATE
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/source/empty_callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl Source for EmptyCallback {

#[inline]
fn sample_rate(&self) -> SampleRate {
nz!(48000)
crate::DEFAULT_SAMPLE_RATE
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/source/from_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ where
src.sample_rate()
} else {
// Dummy value that only happens if the iterator was empty.
nz!(44100)
crate::DEFAULT_SAMPLE_RATE
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/source/sawtooth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ pub struct SawtoothWave {
}

impl SawtoothWave {
const SAMPLE_RATE: SampleRate = nz!(48000);

/// The frequency of the sine.
#[inline]
pub fn new(freq: f32) -> SawtoothWave {
SawtoothWave {
test_saw: SignalGenerator::new(Self::SAMPLE_RATE, freq, Function::Sawtooth),
test_saw: SignalGenerator::new(crate::DEFAULT_SAMPLE_RATE, freq, Function::Sawtooth),
}
}
}
Expand Down Expand Up @@ -56,7 +54,7 @@ impl Source for SawtoothWave {

#[inline]
fn sample_rate(&self) -> SampleRate {
Self::SAMPLE_RATE
crate::DEFAULT_SAMPLE_RATE
}

#[inline]
Expand Down
6 changes: 2 additions & 4 deletions src/source/sine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ pub struct SineWave {
}

impl SineWave {
const SAMPLE_RATE: SampleRate = nz!(48000);

/// The frequency of the sine.
#[inline]
pub fn new(freq: f32) -> SineWave {
SineWave {
test_sine: SignalGenerator::new(Self::SAMPLE_RATE, freq, Function::Sine),
test_sine: SignalGenerator::new(crate::DEFAULT_SAMPLE_RATE, freq, Function::Sine),
}
}
}
Expand Down Expand Up @@ -56,7 +54,7 @@ impl Source for SineWave {

#[inline]
fn sample_rate(&self) -> SampleRate {
Self::SAMPLE_RATE
crate::DEFAULT_SAMPLE_RATE
}

#[inline]
Expand Down
6 changes: 2 additions & 4 deletions src/source/square.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ pub struct SquareWave {
}

impl SquareWave {
const SAMPLE_RATE: SampleRate = nz!(48000);

/// The frequency of the sine.
#[inline]
pub fn new(freq: f32) -> SquareWave {
SquareWave {
test_square: SignalGenerator::new(Self::SAMPLE_RATE, freq, Function::Square),
test_square: SignalGenerator::new(crate::DEFAULT_SAMPLE_RATE, freq, Function::Square),
}
}
}
Expand Down Expand Up @@ -56,7 +54,7 @@ impl Source for SquareWave {

#[inline]
fn sample_rate(&self) -> SampleRate {
Self::SAMPLE_RATE
crate::DEFAULT_SAMPLE_RATE
}

#[inline]
Expand Down
6 changes: 2 additions & 4 deletions src/source/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ pub struct TriangleWave {
}

impl TriangleWave {
const SAMPLE_RATE: SampleRate = nz!(48000);

/// The frequency of the sine.
#[inline]
pub fn new(freq: f32) -> TriangleWave {
TriangleWave {
test_tri: SignalGenerator::new(Self::SAMPLE_RATE, freq, Function::Triangle),
test_tri: SignalGenerator::new(crate::DEFAULT_SAMPLE_RATE, freq, Function::Triangle),
}
}
}
Expand Down Expand Up @@ -56,7 +54,7 @@ impl Source for TriangleWave {

#[inline]
fn sample_rate(&self) -> SampleRate {
Self::SAMPLE_RATE
crate::DEFAULT_SAMPLE_RATE
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/speakers/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl Default for OutputConfig {
fn default() -> Self {
Self {
channel_count: nz!(1),
sample_rate: nz!(44_100),
sample_rate: crate::DEFAULT_SAMPLE_RATE,
buffer_size: BufferSize::default(),
sample_format: cpal::SampleFormat::F32,
}
Expand Down
28 changes: 16 additions & 12 deletions src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ use std::io::{Read, Seek};
use std::marker::Sync;
use std::num::NonZero;

const HZ_44100: SampleRate = nz!(44_100);

/// `cpal::Stream` container. Use `mixer()` method to control output.
///
/// <div class="warning">When dropped playback will end, and the associated
Expand Down Expand Up @@ -128,7 +126,7 @@ impl Default for DeviceSinkConfig {
fn default() -> Self {
Self {
channel_count: nz!(2),
sample_rate: HZ_44100,
sample_rate: crate::DEFAULT_SAMPLE_RATE,
buffer_size: BufferSize::Default,
sample_format: SampleFormat::F32,
}
Expand Down Expand Up @@ -350,8 +348,8 @@ where
self
}

/// Set available parameters from a CPAL supported config. You can get a list of
/// such configurations for an output device using [crate::stream::supported_output_configs()]
/// Set available parameters from a CPAL supported config. To enumerate what a device supports,
/// use [`cpal::Device::supported_output_configs`].
pub fn with_supported_config(
mut self,
config: &cpal::SupportedStreamConfig,
Expand Down Expand Up @@ -573,8 +571,11 @@ impl MixerDeviceSink {
}
}

/// Return all formats supported by the device.
pub fn supported_output_configs(
/// Returns candidate output configurations for the device in preference order.
///
/// For each supported format, yields 48 kHz and 44.1 kHz (where the device supports them),
/// followed by the device's maximum sample rate.
fn supported_output_configs(
device: &cpal::Device,
) -> Result<impl Iterator<Item = cpal::SupportedStreamConfig>, DeviceSinkError> {
let mut supported: Vec<_> = device
Expand All @@ -586,12 +587,15 @@ pub fn supported_output_configs(
Ok(supported.into_iter().flat_map(|sf| {
let max_rate = sf.max_sample_rate();
let min_rate = sf.min_sample_rate();
let mut formats = vec![sf.with_max_sample_rate()];
let preferred_rate = HZ_44100.get();
if preferred_rate < max_rate && preferred_rate > min_rate {
formats.push(sf.with_sample_rate(preferred_rate))
let mut formats = Vec::new();
for rate in [cpal::SAMPLE_RATE_48K, cpal::SAMPLE_RATE_CD] {
if rate >= min_rate && rate <= max_rate {
formats.push(sf.with_sample_rate(rate));
}
}
if !formats.iter().any(|f| f.sample_rate() == max_rate) {
formats.push(sf.with_max_sample_rate());
}
formats.push(sf.with_sample_rate(min_rate));
formats
}))
}
Loading