Skip to content

Commit 282da56

Browse files
committed
refactor: clarify docs and clean up tests
1 parent 1dd54ce commit 282da56

File tree

12 files changed

+49
-60
lines changed

12 files changed

+49
-60
lines changed

benches/effects.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn agc_enabled(bencher: Bencher) {
5757
fn agc_disabled(bencher: Bencher) {
5858
bencher.with_inputs(music_wav).bench_values(|source| {
5959
// Create the AGC source
60-
let amplified_source = source.automatic_gain_control(Default::default);
60+
let amplified_source = source.automatic_gain_control(Default::default());
6161

6262
// Get the control handle and disable AGC
6363
let agc_control = amplified_source.get_agc_control();

src/buffer.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ impl Source for SamplesBuffer {
104104
// sample directly.
105105

106106
let curr_channel = self.pos % self.channels().get() as usize;
107-
let new_pos =
108-
duration_to_float(pos) * self.sample_rate().get() as Float * self.channels().get() as Float;
107+
let new_pos = duration_to_float(pos)
108+
* self.sample_rate().get() as Float
109+
* self.channels().get() as Float;
109110
// saturate pos at the end of the source
110111
let new_pos = new_pos as usize;
111112
let new_pos = new_pos.min(self.data.len());

src/math.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ pub(crate) const NANOS_PER_SEC: u64 = 1_000_000_000;
99
// Re-export float constants with appropriate precision for the Float type.
1010
// This centralizes all cfg gating for constants in one place.
1111
#[cfg(not(feature = "64bit"))]
12-
pub use std::f32::consts::{E, LN_2, LN_10, LOG2_10, LOG2_E, LOG10_2, LOG10_E, PI, TAU};
12+
pub use std::f32::consts::{E, LN_10, LN_2, LOG10_2, LOG10_E, LOG2_10, LOG2_E, PI, TAU};
1313
#[cfg(feature = "64bit")]
14-
pub use std::f64::consts::{E, LN_2, LN_10, LOG2_10, LOG2_E, LOG10_2, LOG10_E, PI, TAU};
14+
pub use std::f64::consts::{E, LN_10, LN_2, LOG10_2, LOG10_E, LOG2_10, LOG2_E, PI, TAU};
1515

1616
/// Linear interpolation between two samples.
1717
///
@@ -255,21 +255,21 @@ mod test {
255255
#[test]
256256
fn convert_linear_to_decibels() {
257257
// Test the inverse conversion function using the same reference data
258-
for (wikipedia_db, linear) in DECIBELS_LINEAR_TABLE {
258+
for (expected_db, linear) in DECIBELS_LINEAR_TABLE {
259259
let actual_db = linear_to_db(linear);
260260

261261
// Sanity check: ensure we're reasonably close to the expected dB value from the table
262262
// This accounts for rounding in both the linear and dB reference values
263-
let magnitude_ratio = if wikipedia_db.abs() > 10.0 * Float::EPSILON {
264-
actual_db / wikipedia_db
263+
let magnitude_ratio = if expected_db.abs() > 10.0 * Float::EPSILON {
264+
actual_db / expected_db
265265
} else {
266266
1.0 // Skip ratio check for values very close to 0 dB
267267
};
268268

269-
if wikipedia_db.abs() > 10.0 * Float::EPSILON {
269+
if expected_db.abs() > 10.0 * Float::EPSILON {
270270
assert!(
271271
magnitude_ratio > 0.99 && magnitude_ratio < 1.01,
272-
"Result differs significantly from table reference for linear {linear}: expected {wikipedia_db}dB, got {actual_db}dB, ratio: {magnitude_ratio:.4}"
272+
"Result differs significantly from table reference for linear {linear}: expected {expected_db}dB, got {actual_db}dB, ratio: {magnitude_ratio:.4}"
273273
);
274274
}
275275
}

src/microphone/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub struct InputConfig {
1212
/// The buffersize, see a thorough explanation in MicrophoneBuilder::with_buffer_size
1313
pub buffer_size: cpal::BufferSize,
1414
/// The sample format used by the microphone.
15-
/// Note we will always convert it to f32
15+
/// Note we will always convert it to `Sample`
1616
pub sample_format: cpal::SampleFormat,
1717
}
1818
impl InputConfig {

src/source/linear_ramp.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,8 @@ where
9090
}
9191

9292
if self.sample_idx.is_multiple_of(self.channels().get() as u64) {
93-
let sample_duration = Duration::from_nanos(
94-
NANOS_PER_SEC / self.input.sample_rate().get() as u64
95-
);
93+
let sample_duration =
94+
Duration::from_nanos(NANOS_PER_SEC / self.input.sample_rate().get() as u64);
9695
self.elapsed += sample_duration;
9796
}
9897

src/source/noise.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl<R: Rng> WhiteUniform<R> {
154154
/// Get the standard deviation of the uniform distribution.
155155
///
156156
/// For uniform distribution [-1.0, 1.0], std_dev = √(1/3) ≈ 0.5774.
157-
pub fn std_dev(&self) -> f32 {
157+
pub fn std_dev(&self) -> Sample {
158158
UNIFORM_VARIANCE.sqrt()
159159
}
160160
}
@@ -209,8 +209,8 @@ impl<R: Rng> WhiteTriangular<R> {
209209
/// Get the standard deviation of the triangular distribution.
210210
///
211211
/// For triangular distribution [-1.0, 1.0] with mode 0.0, std_dev = 2/√6 ≈ 0.8165.
212-
pub fn std_dev(&self) -> f32 {
213-
2.0 / (6.0_f32).sqrt()
212+
pub fn std_dev(&self) -> Sample {
213+
2.0 / Sample::sqrt(6.0)
214214
}
215215
}
216216

@@ -416,7 +416,7 @@ const VELVET_DEFAULT_DENSITY: NonZero<usize> = nz!(2000);
416416
/// Variance of uniform distribution [-1.0, 1.0].
417417
///
418418
/// For uniform distribution U(-1, 1), the variance is (b-a)²/12 = 4/12 = 1/3.
419-
const UNIFORM_VARIANCE: f32 = 1.0 / 3.0;
419+
const UNIFORM_VARIANCE: Sample = 1.0 / 3.0;
420420

421421
/// Pink noise generator - sounds much more natural than white noise.
422422
///
@@ -645,8 +645,7 @@ where
645645
// Center frequency is set to 5Hz, which provides good behavior
646646
// while preventing excessive low-frequency buildup across common sample rates.
647647
let center_freq_hz = 5.0;
648-
let leak_factor =
649-
1.0 - ((2.0 * PI * center_freq_hz) / sample_rate.get() as Float);
648+
let leak_factor = 1.0 - ((2.0 * PI * center_freq_hz) / sample_rate.get() as Float);
650649

651650
// Calculate the scaling factor to normalize output based on leak factor.
652651
// This ensures consistent output level regardless of the leak factor value.
@@ -1044,15 +1043,6 @@ mod tests {
10441043
near_zero_count > total_samples / 2,
10451044
"Triangular distribution should favor values near zero"
10461045
);
1047-
1048-
// Test std_dev method
1049-
let generator = WhiteTriangular::new(TEST_SAMPLE_RATE);
1050-
let expected_std_dev = 2.0 / (6.0_f32).sqrt();
1051-
assert!(
1052-
(generator.std_dev() - expected_std_dev).abs() < f32::EPSILON,
1053-
"Triangular std_dev should be 2/sqrt(6) ≈ 0.8165, got {}",
1054-
generator.std_dev()
1055-
);
10561046
}
10571047

10581048
#[test]

src/source/signal_generator.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! Generator sources for various periodic test waveforms.
22
//!
33
//! This module provides several periodic, deterministic waveforms for testing other sources and
4-
//! for simple additive sound synthesis. Every source is monoaural and in the codomain [-1.0f32,
5-
//! 1.0f32].
4+
//! for simple additive sound synthesis. Every source is monoaural and in the codomain [-1.0, 1.0].
65
//!
76
//! # Example
87
//!
@@ -176,7 +175,7 @@ mod tests {
176175

177176
#[test]
178177
fn square() {
179-
let mut wf = SignalGenerator::new(nz!(2000), 500.0f32, Function::Square);
178+
let mut wf = SignalGenerator::new(nz!(2000), 500.0, Function::Square);
180179
assert_eq!(wf.next(), Some(1.0));
181180
assert_eq!(wf.next(), Some(1.0));
182181
assert_eq!(wf.next(), Some(-1.0));
@@ -189,7 +188,7 @@ mod tests {
189188

190189
#[test]
191190
fn triangle() {
192-
let mut wf = SignalGenerator::new(nz!(8000), 1000.0f32, Function::Triangle);
191+
let mut wf = SignalGenerator::new(nz!(8000), 1000.0, Function::Triangle);
193192
assert_eq!(wf.next(), Some(-1.0));
194193
assert_eq!(wf.next(), Some(-0.5));
195194
assert_eq!(wf.next(), Some(0.0));
@@ -210,7 +209,7 @@ mod tests {
210209

211210
#[test]
212211
fn saw() {
213-
let mut wf = SignalGenerator::new(nz!(200), 50.0f32, Function::Sawtooth);
212+
let mut wf = SignalGenerator::new(nz!(200), 50.0, Function::Sawtooth);
214213
assert_eq!(wf.next(), Some(0.0));
215214
assert_eq!(wf.next(), Some(0.5));
216215
assert_eq!(wf.next(), Some(-1.0));

src/source/skip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ mod tests {
169169
use crate::buffer::SamplesBuffer;
170170
use crate::common::{ChannelCount, SampleRate};
171171
use crate::math::nz;
172-
use crate::Sample;
173172
use crate::source::Source;
173+
use crate::Sample;
174174
use dasp_sample::Sample as DaspSample;
175175

176176
fn test_skip_duration_samples_left(

src/wav_output.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::common::assert_error_traits;
22
use crate::Sample;
33
use crate::Source;
4+
use dasp_sample::Sample as DaspSample;
45
use hound::{SampleFormat, WavSpec};
56
use std::io::{self, Write};
67
use std::path;
@@ -77,7 +78,7 @@ pub fn wav_to_writer(
7778
let whole_frames = WholeFrames::new(source);
7879
for sample in whole_frames {
7980
writer
80-
.write_sample(sample)
81+
.write_sample(sample.to_sample::<f32>())
8182
.map_err(Arc::new)
8283
.map_err(ToWavError::Writing)?;
8384
}
@@ -131,6 +132,7 @@ impl<I: Iterator<Item = Sample>> Iterator for WholeFrames<I> {
131132
mod test {
132133
use super::wav_to_file;
133134
use crate::{Sample, Source};
135+
use dasp_sample::Sample as DaspSample;
134136
use std::io::BufReader;
135137
use std::time::Duration;
136138

@@ -152,11 +154,20 @@ mod test {
152154
assert_eq!(reference.sample_rate().get(), reader.spec().sample_rate);
153155
assert_eq!(reference.channels().get(), reader.spec().channels);
154156

155-
let actual_samples: Vec<Sample> = reader.samples::<Sample>().map(|x| x.unwrap()).collect();
156-
let expected_samples: Vec<Sample> = reference.collect();
157-
assert!(
158-
expected_samples == actual_samples,
159-
"wav samples do not match the source"
157+
// WAV files always use f32 samples (hound limitation)
158+
let actual_samples: Vec<f32> = reader.samples::<f32>().map(|x| x.unwrap()).collect();
159+
let expected_samples: Vec<f32> = reference
160+
.into_iter()
161+
.map(|s| s.to_sample::<f32>())
162+
.collect();
163+
164+
assert_eq!(
165+
actual_samples.len(),
166+
expected_samples.len(),
167+
"sample counts should match"
160168
);
169+
for (actual, expected) in actual_samples.iter().zip(expected_samples.iter()) {
170+
assert_eq!(actual, expected, "wav samples do not match the source");
171+
}
161172
}
162173
}

tests/channel_volume.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ fn channel_volume_with_queue() {
2727
assert_output_only_on_first_two_channels(queue, 6);
2828
}
2929

30-
fn assert_output_only_on_first_two_channels(
31-
source: impl Source<Item = Sample>,
32-
channels: usize,
33-
) {
30+
fn assert_output_only_on_first_two_channels(source: impl Source<Item = Sample>, channels: usize) {
3431
let mut frame_number = 0;
3532
let mut samples_in_frame = Vec::new();
3633

0 commit comments

Comments
 (0)