Skip to content

Commit b94688e

Browse files
committed
refactor: replace interpolator rate methods with set_bandwidth
1 parent 9668870 commit b94688e

File tree

4 files changed

+13
-43
lines changed

4 files changed

+13
-43
lines changed

CHANGELOG.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
- Fixed aliasing in Sinc interpolator when downsampling by adding automatic
44
anti-aliasing filter cutoff adjustment. The `Interpolator` trait now includes
5-
`set_hz_to_hz`, `set_playback_hz_scale`, and `set_sample_hz_scale` methods
6-
(with default no-op implementations) that are called automatically by the
7-
corresponding `Converter` methods to configure rate-dependent parameters.
5+
a `set_bandwidth` method (with default no-op implementation) that is called
6+
automatically by `Converter`.
87
- Renamed `window-hanning` to `window-hann`
98
- Made `IntoInterleavedSamples` and `IntoInterleavedSamplesIterator` stop
109
yielding samples when the underlying signal gets exhausted. This is a breaking

dasp_interpolate/src/lib.rs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,6 @@ pub mod sinc;
3838
///
3939
/// Implementations should keep track of the necessary data both before and after the current
4040
/// frame.
41-
///
42-
/// # Rate Configuration
43-
///
44-
/// Some interpolators require sample rate information to operate correctly (e.g., sinc
45-
/// interpolation needs the rate ratio for anti-aliasing). The `set_hz_to_hz`,
46-
/// `set_playback_hz_scale`, and `set_sample_hz_scale` methods provide alternative ways
47-
/// to configure this - use whichever matches the information available. These methods
48-
/// are called automatically by the corresponding `Converter` methods.
49-
///
50-
/// Interpolators that don't need rate information (floor, linear) can use the default
51-
/// no-op implementations.
5241
pub trait Interpolator {
5342
/// The type of frame over which the interpolate may operate.
5443
type Frame: Frame;
@@ -65,12 +54,8 @@ pub trait Interpolator {
6554
/// Call this when there's a break in the continuity of the input data stream.
6655
fn reset(&mut self);
6756

68-
/// Configures the interpolator from absolute sample rates.
69-
fn set_hz_to_hz(&mut self, _source_hz: f64, _target_hz: f64) {}
70-
71-
/// Configures the interpolator from playback rate scale (`source_hz / target_hz`).
72-
fn set_playback_hz_scale(&mut self, _scale: f64) {}
73-
74-
/// Configures the interpolator from sample rate scale (`target_hz / source_hz`).
75-
fn set_sample_hz_scale(&mut self, _scale: f64) {}
57+
/// Configures filter bandwidth for anti-aliasing. No-op for non-filtering interpolators.
58+
///
59+
/// For downsampling, set to `target_hz / source_hz` to prevent aliasing.
60+
fn set_bandwidth(&mut self, _bandwidth: f64) {}
7661
}

dasp_interpolate/src/sinc/mod.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,7 @@ where
145145
}
146146
}
147147

148-
fn set_hz_to_hz(&mut self, source_hz: f64, target_hz: f64) {
149-
self.bandwidth = (target_hz / source_hz).min(1.0);
150-
}
151-
152-
fn set_playback_hz_scale(&mut self, scale: f64) {
153-
self.bandwidth = (1.0 / scale).min(1.0);
154-
}
155-
156-
fn set_sample_hz_scale(&mut self, scale: f64) {
157-
self.bandwidth = scale.min(1.0);
148+
fn set_bandwidth(&mut self, bandwidth: f64) {
149+
self.bandwidth = bandwidth.clamp(f64::MIN_POSITIVE, 1.0);
158150
}
159151
}

dasp_signal/src/interpolate.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ where
3232
/// Construct a new `Converter` from the source frames and the source and target sample rates
3333
/// (in Hz).
3434
///
35-
/// This method calls `interpolator.set_hz_to_hz(source_hz, target_hz)` internally.
35+
/// Configures the interpolator's bandwidth for anti-aliasing when downsampling.
3636
#[inline]
3737
pub fn from_hz_to_hz(source: S, mut interpolator: I, source_hz: f64, target_hz: f64) -> Self {
38-
interpolator.set_hz_to_hz(source_hz, target_hz);
38+
interpolator.set_bandwidth(target_hz / source_hz);
3939
Self::scale_playback_hz(source, interpolator, source_hz / target_hz)
4040
}
4141

@@ -75,33 +75,27 @@ where
7575
/// Update the `source_to_target_ratio` internally given the source and target hz.
7676
///
7777
/// This method might be useful for changing the sample rate during playback.
78-
///
79-
/// This method calls `interpolator.set_hz_to_hz(source_hz, target_hz)` internally.
8078
#[inline]
8179
pub fn set_hz_to_hz(&mut self, source_hz: f64, target_hz: f64) {
82-
self.interpolator.set_hz_to_hz(source_hz, target_hz);
80+
self.interpolator.set_bandwidth(target_hz / source_hz);
8381
self.set_playback_hz_scale(source_hz / target_hz)
8482
}
8583

8684
/// Update the `source_to_target_ratio` internally given a new **playback rate** multiplier.
8785
///
8886
/// This method is useful for dynamically changing rates.
89-
///
90-
/// This method calls `interpolator.set_playback_hz_scale(scale)` internally.
9187
#[inline]
9288
pub fn set_playback_hz_scale(&mut self, scale: f64) {
93-
self.interpolator.set_playback_hz_scale(scale);
89+
self.interpolator.set_bandwidth(1.0 / scale);
9490
self.source_to_target_ratio = scale;
9591
}
9692

9793
/// Update the `source_to_target_ratio` internally given a new **sample rate** multiplier.
9894
///
9995
/// This method is useful for dynamically changing rates.
100-
///
101-
/// This method calls `interpolator.set_sample_hz_scale(scale)` internally.
10296
#[inline]
10397
pub fn set_sample_hz_scale(&mut self, scale: f64) {
104-
self.interpolator.set_sample_hz_scale(scale);
98+
self.interpolator.set_bandwidth(scale);
10599
self.set_playback_hz_scale(1.0 / scale);
106100
}
107101

0 commit comments

Comments
 (0)