Skip to content

Commit 1b66519

Browse files
committed
refactor: use BitDepth for bits_per_sample
- Introduce BitDepth as a newtype for non-zero u32 - Update Source trait and all implementations to use Option<BitDepth> - Update decoders, sources, and tests to use BitDepth instead of u32 for bit depth - Replace NonZero usage for sample rate and channel count with SampleRate and ChannelCount types where appropriate - Update documentation and examples to reflect new types fix: change bits_per_sample to return Option<BitDepth>
1 parent 81e23f6 commit 1b66519

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+250
-245
lines changed

benches/pipeline.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use std::num::NonZero;
21
use std::time::Duration;
32

43
use divan::Bencher;
5-
use rodio::ChannelCount;
64
use rodio::{source::UniformSourceIterator, Source};
5+
use rodio::{ChannelCount, SampleRate};
76

87
mod shared;
98
use shared::music_wav;
@@ -36,7 +35,7 @@ fn long(bencher: Bencher) {
3635
let resampled = UniformSourceIterator::new(
3736
effects_applied,
3837
ChannelCount::new(2).unwrap(),
39-
NonZero::new(40_000).unwrap(),
38+
SampleRate::new(40_000).unwrap(),
4039
);
4140
resampled.for_each(divan::black_box_drop)
4241
})

benches/shared.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use std::io::Cursor;
22
use std::time::Duration;
33
use std::vec;
44

5-
use rodio::{ChannelCount, Sample, SampleRate, Source};
5+
use rodio::{BitDepth, ChannelCount, Sample, SampleRate, Source};
66

77
pub struct TestSource {
88
samples: vec::IntoIter<Sample>,
99
channels: ChannelCount,
1010
sample_rate: SampleRate,
11-
bits_per_sample: Option<u32>,
11+
bits_per_sample: Option<BitDepth>,
1212
total_duration: Duration,
1313
}
1414

@@ -50,7 +50,7 @@ impl Source for TestSource {
5050
}
5151

5252
#[inline]
53-
fn bits_per_sample(&self) -> Option<u32> {
53+
fn bits_per_sample(&self) -> Option<BitDepth> {
5454
self.bits_per_sample
5555
}
5656
}

examples/custom_config.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use cpal::traits::HostTrait;
22
use cpal::{BufferSize, SampleFormat};
33
use rodio::source::SineWave;
4-
use rodio::Source;
4+
use rodio::{SampleRate, Source};
55
use std::error::Error;
6-
use std::num::NonZero;
76
use std::thread;
87
use std::time::Duration;
98

@@ -16,7 +15,7 @@ fn main() -> Result<(), Box<dyn Error>> {
1615
// No need to set all parameters explicitly here,
1716
// the defaults were set from the device's description.
1817
.with_buffer_size(BufferSize::Fixed(256))
19-
.with_sample_rate(NonZero::new(48_000).unwrap())
18+
.with_sample_rate(SampleRate::new(48_000).unwrap())
2019
.with_sample_format(SampleFormat::F32)
2120
// Note that the function below still tries alternative configs if the specified one fails.
2221
// If you need to only use the exact specified configuration,

examples/mix_multiple_sources.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
use rodio::mixer;
21
use rodio::source::{SineWave, Source};
2+
use rodio::{mixer, ChannelCount, SampleRate};
33
use std::error::Error;
4-
use std::num::NonZero;
54
use std::time::Duration;
65

76
fn main() -> Result<(), Box<dyn Error>> {
87
// Construct a dynamic controller and mixer, stream_handle, and sink.
9-
let (controller, mixer) = mixer::mixer(NonZero::new(2).unwrap(), NonZero::new(44_100).unwrap());
8+
let (controller, mixer) = mixer::mixer(
9+
ChannelCount::new(2).unwrap(),
10+
SampleRate::new(44_100).unwrap(),
11+
);
1012
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
1113
let sink = rodio::Sink::connect_new(stream_handle.mixer());
1214

examples/signal_generator.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
//! Test signal generator example.
22
33
use std::error::Error;
4-
use std::num::NonZero;
4+
5+
use rodio::SampleRate;
56

67
fn main() -> Result<(), Box<dyn Error>> {
78
use rodio::source::{chirp, Function, SignalGenerator, Source};
@@ -12,7 +13,7 @@ fn main() -> Result<(), Box<dyn Error>> {
1213

1314
let test_signal_duration = Duration::from_millis(1000);
1415
let interval_duration = Duration::from_millis(1500);
15-
let sample_rate = NonZero::new(48000).unwrap();
16+
let sample_rate = SampleRate::new(48000).unwrap();
1617

1718
println!("Playing 1000 Hz tone");
1819
stream_handle.mixer().add(

src/buffer.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
//! # Example
66
//!
77
//! ```
8-
//! use rodio::buffer::SamplesBuffer;
9-
//! use core::num::NonZero;
10-
//! let _ = SamplesBuffer::new(NonZero::new(1).unwrap(), NonZero::new(44100).unwrap(), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
8+
//! use rodio::{ChannelCount, SampleRate, buffer::SamplesBuffer};
9+
//! let _ = SamplesBuffer::new(ChannelCount::new(1).unwrap(), SampleRate::new(44100).unwrap(), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
1110
//! ```
1211
//!
1312
1413
use crate::common::{ChannelCount, SampleRate};
1514
use crate::source::{SeekError, UniformSourceIterator};
16-
use crate::{Sample, Source};
15+
use crate::{BitDepth, Sample, Source};
1716
use std::sync::Arc;
1817
use std::time::Duration;
1918

@@ -92,7 +91,7 @@ impl Source for SamplesBuffer {
9291
}
9392

9493
#[inline]
95-
fn bits_per_sample(&self) -> Option<u32> {
94+
fn bits_per_sample(&self) -> Option<BitDepth> {
9695
None
9796
}
9897

src/common.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ use std::num::NonZero;
44
/// Stream sample rate (a frame rate or samples per second per channel).
55
pub type SampleRate = NonZero<u32>;
66

7-
/// Number of channels in a stream. Can never be Zero
7+
/// Number of channels in a stream. Can never be zero.
88
pub type ChannelCount = NonZero<u16>;
99

10+
/// Number of bits per sample. Can never be zero.
11+
pub type BitDepth = NonZero<u32>;
12+
1013
/// Represents value of a single sample.
1114
/// Silence corresponds to the value `0.0`. The expected amplitude range is -1.0...1.0.
1215
/// Values below and above this range are clipped in conversion to other sample types.

src/decoder/flac.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,7 @@ use dasp_sample::Sample as _;
7272
use dasp_sample::I24;
7373

7474
use super::{utils, Settings};
75-
use crate::{
76-
common::{ChannelCount, Sample, SampleRate},
77-
source::SeekError,
78-
Source,
79-
};
75+
use crate::{source::SeekError, BitDepth, ChannelCount, Sample, SampleRate, Source};
8076

8177
/// Reader options for `claxon` FLAC decoder.
8278
///
@@ -152,7 +148,7 @@ where
152148
/// Preserved from the original FLAC stream metadata and used for proper
153149
/// sample conversion during iteration. FLAC supports various bit depths
154150
/// including non-standard ones like 12 and 20-bit.
155-
bits_per_sample: u32,
151+
bits_per_sample: BitDepth,
156152

157153
/// Sample rate in Hz.
158154
///
@@ -299,7 +295,8 @@ where
299295
current_block: Vec::with_capacity(max_block_size),
300296
current_block_samples_per_channel: 1,
301297
current_block_off: 0,
302-
bits_per_sample: spec.bits_per_sample,
298+
bits_per_sample: BitDepth::new(spec.bits_per_sample)
299+
.expect("flac should never have zero bits per sample"),
303300
sample_rate: SampleRate::new(sample_rate)
304301
.expect("flac data should never have a zero sample rate"),
305302
channels: ChannelCount::new(
@@ -409,7 +406,7 @@ where
409406
///
410407
/// Always returns `Some(depth)` for valid FLAC streams.
411408
#[inline]
412-
fn bits_per_sample(&self) -> Option<u32> {
409+
fn bits_per_sample(&self) -> Option<BitDepth> {
413410
Some(self.bits_per_sample)
414411
}
415412

@@ -564,7 +561,7 @@ where
564561
let raw_val = self.current_block[real_offset];
565562
self.current_block_off += 1;
566563
self.samples_read += 1;
567-
let bits = self.bits_per_sample;
564+
let bits = self.bits_per_sample.get();
568565
let real_val = match bits {
569566
8 => (raw_val as i8).to_sample(),
570567
16 => (raw_val as i16).to_sample(),

src/decoder/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use crate::{
5959
common::{assert_error_traits, ChannelCount, SampleRate},
6060
math::nz,
6161
source::{SeekError, Source},
62-
Sample,
62+
BitDepth, Sample,
6363
};
6464

6565
pub mod builder;
@@ -269,7 +269,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
269269
/// For lossy formats this should always return `None` as bit depth is not a meaningful
270270
/// concept for compressed audio.
271271
#[inline]
272-
fn bits_per_sample(&self) -> Option<u32> {
272+
fn bits_per_sample(&self) -> Option<BitDepth> {
273273
match self {
274274
#[cfg(feature = "hound")]
275275
DecoderImpl::Wav(source) => source.bits_per_sample(),
@@ -951,7 +951,7 @@ where
951951
}
952952

953953
#[inline]
954-
fn bits_per_sample(&self) -> Option<u32> {
954+
fn bits_per_sample(&self) -> Option<BitDepth> {
955955
self.0.bits_per_sample()
956956
}
957957

@@ -1131,7 +1131,7 @@ where
11311131

11321132
/// Returns the bits per sample of the underlying decoder, if available.
11331133
#[inline]
1134-
fn bits_per_sample(&self) -> Option<u32> {
1134+
fn bits_per_sample(&self) -> Option<BitDepth> {
11351135
self.inner.as_ref()?.bits_per_sample()
11361136
}
11371137

src/decoder/mp3.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
5555
use std::{
5656
io::{Read, Seek, SeekFrom},
57-
num::NonZero,
5857
sync::Arc,
5958
time::Duration,
6059
};
@@ -66,9 +65,7 @@ use minimp3_fixed as minimp3;
6665

6766
use super::{utils, Settings};
6867
use crate::{
69-
common::{ChannelCount, Sample, SampleRate},
70-
decoder::builder::SeekMode,
71-
source::SeekError,
68+
decoder::builder::SeekMode, source::SeekError, BitDepth, ChannelCount, Sample, SampleRate,
7269
Source,
7370
};
7471

@@ -354,8 +351,9 @@ where
354351
start_byte,
355352
current_span: Some(current_span),
356353
current_span_offset: 0,
357-
channels: NonZero::new(channels as _).expect("mp3's have at least one channel"),
358-
sample_rate: NonZero::new(sample_rate as _).expect("mp3's have a non zero sample rate"),
354+
channels: ChannelCount::new(channels as _).expect("mp3's have at least one channel"),
355+
sample_rate: SampleRate::new(sample_rate as _)
356+
.expect("mp3's have a non zero sample rate"),
359357
samples_read: 0,
360358
total_samples,
361359
total_duration,
@@ -537,7 +535,7 @@ where
537535
/// This method always returns `None` for MP3 streams as bit depth is not
538536
/// a meaningful concept for lossy compressed audio formats.
539537
#[inline]
540-
fn bits_per_sample(&self) -> Option<u32> {
538+
fn bits_per_sample(&self) -> Option<BitDepth> {
541539
None
542540
}
543541

@@ -716,7 +714,7 @@ where
716714

717715
// Update channels if they changed (can vary between MP3 frames)
718716
self.channels =
719-
NonZero::new(span.channels as _).expect("mp3's have at least one channel");
717+
ChannelCount::new(span.channels as _).expect("mp3's have at least one channel");
720718
// Sample rate is fixed per MP3 stream, so no need to update
721719
self.current_span = Some(span);
722720
self.current_span_offset = 0;

0 commit comments

Comments
 (0)