Skip to content

Commit 67e759a

Browse files
committed
rename ch! macro to nz and make SampleRate NonZero
Similar to the channels situation a lot of bugs seem to be caused by zero sample_rate. Since audio can literally not play at zero speed it makes no sense to have zero sample_rate's.
1 parent 3fb371d commit 67e759a

Some content is hidden

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

45 files changed

+241
-220
lines changed

benches/pipeline.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::num::NonZero;
12
use std::time::Duration;
23

34
use divan::Bencher;
@@ -32,8 +33,11 @@ fn long(bencher: Bencher) {
3233
.buffered()
3334
.reverb(Duration::from_secs_f32(0.05), 0.3)
3435
.skippable();
35-
let resampled =
36-
UniformSourceIterator::new(effects_applied, ChannelCount::new(2).unwrap(), 40_000);
36+
let resampled = UniformSourceIterator::new(
37+
effects_applied,
38+
ChannelCount::new(2).unwrap(),
39+
NonZero::new(40_000).unwrap(),
40+
);
3741
resampled.for_each(divan::black_box_drop)
3842
})
3943
}

benches/resampler.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rodio::source::UniformSourceIterator;
44
mod shared;
55
use shared::music_wav;
66

7-
use rodio::Source;
7+
use rodio::{SampleRate, Source};
88

99
fn main() {
1010
divan::main();
@@ -31,6 +31,7 @@ const COMMON_SAMPLE_RATES: [u32; 12] = [
3131

3232
#[divan::bench(args = COMMON_SAMPLE_RATES)]
3333
fn resample_to(bencher: Bencher, target_sample_rate: u32) {
34+
let target_sample_rate = SampleRate::new(target_sample_rate).unwrap();
3435
bencher
3536
.with_inputs(|| {
3637
let source = music_wav();

benches/shared.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rodio::{ChannelCount, Sample, SampleRate, Source};
77
pub struct TestSource {
88
samples: vec::IntoIter<Sample>,
99
channels: ChannelCount,
10-
sample_rate: u32,
10+
sample_rate: SampleRate,
1111
total_duration: Duration,
1212
}
1313

examples/custom_config.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use cpal::{BufferSize, SampleFormat};
33
use rodio::source::SineWave;
44
use rodio::Source;
55
use std::error::Error;
6+
use std::num::NonZero;
67
use std::thread;
78
use std::time::Duration;
89

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

examples/mix_multiple_sources.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::time::Duration;
66

77
fn main() -> Result<(), Box<dyn Error>> {
88
// Construct a dynamic controller and mixer, stream_handle, and sink.
9-
let (controller, mixer) = mixer::mixer(NonZero::new(2).unwrap(), 44_100);
9+
let (controller, mixer) = mixer::mixer(NonZero::new(2).unwrap(), NonZero::new(44_100).unwrap());
1010
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
1111
let sink = rodio::Sink::connect_new(&stream_handle.mixer());
1212

examples/signal_generator.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Test signal generator example.
22
33
use std::error::Error;
4+
use std::num::NonZero;
45

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

1213
let test_signal_duration = Duration::from_millis(1000);
1314
let interval_duration = Duration::from_millis(1500);
14-
let sample_rate = 48000;
15+
let sample_rate = NonZero::new(48000).unwrap();
1516

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

src/buffer.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//! ```
88
//! use rodio::buffer::SamplesBuffer;
99
//! use rodio::ChannelCount;
10-
//! let _ = SamplesBuffer::new(ChannelCount::new(1).unwrap(), 44100, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
10+
//! let _ = SamplesBuffer::new(ChannelCount::new(1).unwrap(), nz!(44100), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
1111
//! ```
1212
//!
1313
@@ -39,11 +39,9 @@ impl SamplesBuffer {
3939
where
4040
D: Into<Vec<Sample>>,
4141
{
42-
assert!(sample_rate >= 1);
43-
4442
let data = data.into();
4543
let duration_ns = 1_000_000_000u64.checked_mul(data.len() as u64).unwrap()
46-
/ sample_rate as u64
44+
/ sample_rate.get() as u64
4745
/ channels.get() as u64;
4846
let duration = Duration::new(
4947
duration_ns / 1_000_000_000,
@@ -89,7 +87,8 @@ impl Source for SamplesBuffer {
8987
// sample directly.
9088

9189
let curr_channel = self.pos % self.channels().get() as usize;
92-
let new_pos = pos.as_secs_f32() * self.sample_rate() as f32 * self.channels().get() as f32;
90+
let new_pos =
91+
pos.as_secs_f32() * self.sample_rate().get() as f32 * self.channels().get() as f32;
9392
// saturate pos at the end of the source
9493
let new_pos = new_pos as usize;
9594
let new_pos = new_pos.min(self.data.len());
@@ -122,31 +121,31 @@ impl Iterator for SamplesBuffer {
122121
#[cfg(test)]
123122
mod tests {
124123
use crate::buffer::SamplesBuffer;
125-
use crate::math::ch;
124+
use crate::math::nz;
126125
use crate::source::Source;
127126

128127
#[test]
129128
fn basic() {
130-
let _ = SamplesBuffer::new(ch!(1), 44100, vec![0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
129+
let _ = SamplesBuffer::new(nz!(1), nz!(44100), vec![0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
131130
}
132131

133132
#[test]
134133
#[should_panic]
135134
fn panic_if_zero_sample_rate() {
136-
SamplesBuffer::new(ch!(1), 0, vec![0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
135+
SamplesBuffer::new(nz!(1), nz!(0), vec![0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
137136
}
138137

139138
#[test]
140139
fn duration_basic() {
141-
let buf = SamplesBuffer::new(ch!(2), 2, vec![0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
140+
let buf = SamplesBuffer::new(nz!(2), nz!(2), vec![0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
142141
let dur = buf.total_duration().unwrap();
143142
assert_eq!(dur.as_secs(), 1);
144143
assert_eq!(dur.subsec_nanos(), 500_000_000);
145144
}
146145

147146
#[test]
148147
fn iteration() {
149-
let mut buf = SamplesBuffer::new(ch!(1), 44100, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
148+
let mut buf = SamplesBuffer::new(nz!(1), nz!(44100), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
150149
assert_eq!(buf.next(), Some(1.0));
151150
assert_eq!(buf.next(), Some(2.0));
152151
assert_eq!(buf.next(), Some(3.0));
@@ -165,8 +164,8 @@ mod tests {
165164

166165
#[test]
167166
fn channel_order_stays_correct() {
168-
const SAMPLE_RATE: SampleRate = 100;
169-
const CHANNELS: ChannelCount = ch!(2);
167+
const SAMPLE_RATE: SampleRate = nz!(100);
168+
const CHANNELS: ChannelCount = nz!(2);
170169
let mut buf = SamplesBuffer::new(
171170
CHANNELS,
172171
SAMPLE_RATE,
@@ -178,7 +177,7 @@ mod tests {
178177
buf.try_seek(Duration::from_secs(5)).unwrap();
179178
assert_eq!(
180179
buf.next(),
181-
Some(5.0 * SAMPLE_RATE as f32 * CHANNELS.get() as f32)
180+
Some(5.0 * SAMPLE_RATE.get() as f32 * CHANNELS.get() as f32)
182181
);
183182

184183
assert!(buf.next().is_some_and(|s| s.trunc() as i32 % 2 == 1));

src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::num::NonZero;
22

33
/// Stream sample rate (a frame rate or samples per second per channel).
4-
pub type SampleRate = u32;
4+
pub type SampleRate = NonZero<u32>;
55

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

src/conversions/channels.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -108,37 +108,37 @@ impl<I> ExactSizeIterator for ChannelCountConverter<I> where I: ExactSizeIterato
108108
mod test {
109109
use super::ChannelCountConverter;
110110
use crate::common::ChannelCount;
111-
use crate::math::ch;
111+
use crate::math::nz;
112112
use crate::Sample;
113113

114114
#[test]
115115
fn remove_channels() {
116116
let input = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
117117
let output =
118-
ChannelCountConverter::new(input.into_iter(), ch!(3), ch!(2)).collect::<Vec<_>>();
118+
ChannelCountConverter::new(input.into_iter(), nz!(3), nz!(2)).collect::<Vec<_>>();
119119
assert_eq!(output, [1.0, 2.0, 4.0, 5.0]);
120120

121121
let input = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
122122
let output =
123-
ChannelCountConverter::new(input.into_iter(), ch!(4), ch!(1)).collect::<Vec<_>>();
123+
ChannelCountConverter::new(input.into_iter(), nz!(4), nz!(1)).collect::<Vec<_>>();
124124
assert_eq!(output, [1.0, 5.0]);
125125
}
126126

127127
#[test]
128128
fn add_channels() {
129129
let input = vec![1.0, 2.0, 3.0, 4.0];
130130
let output =
131-
ChannelCountConverter::new(input.into_iter(), ch!(1), ch!(2)).collect::<Vec<_>>();
131+
ChannelCountConverter::new(input.into_iter(), nz!(1), nz!(2)).collect::<Vec<_>>();
132132
assert_eq!(output, [1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0]);
133133

134134
let input = vec![1.0, 2.0];
135135
let output =
136-
ChannelCountConverter::new(input.into_iter(), ch!(1), ch!(4)).collect::<Vec<_>>();
136+
ChannelCountConverter::new(input.into_iter(), nz!(1), nz!(4)).collect::<Vec<_>>();
137137
assert_eq!(output, [1.0, 1.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0]);
138138

139139
let input = vec![1.0, 2.0, 3.0, 4.0];
140140
let output =
141-
ChannelCountConverter::new(input.into_iter(), ch!(2), ch!(4)).collect::<Vec<_>>();
141+
ChannelCountConverter::new(input.into_iter(), nz!(2), nz!(4)).collect::<Vec<_>>();
142142
assert_eq!(output, [1.0, 2.0, 0.0, 0.0, 3.0, 4.0, 0.0, 0.0]);
143143
}
144144

@@ -155,24 +155,24 @@ mod test {
155155
assert_eq!(converter.size_hint(), (0, Some(0)));
156156
}
157157

158-
test(&[1.0, 2.0, 3.0], ch!(1), ch!(2));
159-
test(&[1.0, 2.0, 3.0, 4.0], ch!(2), ch!(4));
160-
test(&[1.0, 2.0, 3.0, 4.0], ch!(4), ch!(2));
161-
test(&[1.0, 2.0, 3.0, 4.0, 5.0, 6.0], ch!(3), ch!(8));
162-
test(&[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], ch!(4), ch!(1));
158+
test(&[1.0, 2.0, 3.0], nz!(1), nz!(2));
159+
test(&[1.0, 2.0, 3.0, 4.0], nz!(2), nz!(4));
160+
test(&[1.0, 2.0, 3.0, 4.0], nz!(4), nz!(2));
161+
test(&[1.0, 2.0, 3.0, 4.0, 5.0, 6.0], nz!(3), nz!(8));
162+
test(&[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], nz!(4), nz!(1));
163163
}
164164

165165
#[test]
166166
fn len_more() {
167167
let input = vec![1.0, 2.0, 3.0, 4.0];
168-
let output = ChannelCountConverter::new(input.into_iter(), ch!(2), ch!(3));
168+
let output = ChannelCountConverter::new(input.into_iter(), nz!(2), nz!(3));
169169
assert_eq!(output.len(), 6);
170170
}
171171

172172
#[test]
173173
fn len_less() {
174174
let input = vec![1.0, 2.0, 3.0, 4.0];
175-
let output = ChannelCountConverter::new(input.into_iter(), ch!(2), ch!(1));
175+
let output = ChannelCountConverter::new(input.into_iter(), nz!(2), nz!(1));
176176
assert_eq!(output.len(), 2);
177177
}
178178
}

0 commit comments

Comments
 (0)