A Rust port of the Signalsmith DSP C++ library, providing various DSP (Digital Signal Processing) algorithms for audio and signal processing. This library implements the same high-quality algorithms as the original C++ library, optimized for Rust performance and ergonomics.
- FFT: Fast Fourier Transform implementation optimized for sizes that are products of 2^a * 3^b, with both complex and real-valued implementations
- Filters: Biquad filters with various configurations (lowpass, highpass, bandpass, etc.) and design methods (Butterworth, cookbook)
- Delay Lines: Efficient delay line implementation with multiple interpolation methods (nearest, linear, cubic)
- Curves: Cubic curve interpolation with control over slope and curvature
- Windows: Window functions for spectral processing (Hann, Hamming, Kaiser, Blackman-Harris, etc.)
- Envelopes: LFOs and envelope generators with precise control and minimal aliasing
- Spectral Processing: Tools for spectral manipulation, phase vocoding, and frequency-domain operations
- Time Stretching: High-quality time stretching and pitch shifting using phase vocoder techniques
- STFT: Short-time Fourier transform implementation with overlap-add processing
- Mixing Utilities: Multi-channel mixing matrices and stereo-to-multi-channel conversion
- Linear Algebra: Expression template system for efficient vector operations
- no_std Support: Can be used in environments without the standard library, with optional
alloc
feature - Spacing (Room Reverb): Simulate room acoustics with customizable geometry, early reflections, and multi-channel output
Add this to your Cargo.toml
:
[dependencies]
signalsmith-dsp = "0.0.1"
use signalsmith_dsp::fft::{SimpleFFT, SimpleRealFFT};
use num_complex::Complex;
fn fft_example() {
// Create a new FFT instance for size 1024
let fft = SimpleFFT::<f32>::new(1024);
// Input and output buffers
let mut time_domain = vec![Complex::new(0.0, 0.0); 1024];
let mut freq_domain = vec![Complex::new(0.0, 0.0); 1024];
// Fill input with a sine wave
for i in 0..1024 {
time_domain[i] = Complex::new((i as f32 * 0.1).sin(), 0.0);
}
// Perform forward FFT
fft.fft(&time_domain, &mut freq_domain);
// Process in frequency domain if needed
// Perform inverse FFT
fft.ifft(&freq_domain, &mut time_domain);
}
use signalsmith_dsp::filters::{Biquad, BiquadDesign, FilterType};
fn filter_example() {
// Create a new biquad filter
let mut filter = Biquad::<f32>::new(true);
// Configure as a lowpass filter at 1000 Hz with Q=0.7 (assuming 44.1 kHz sample rate)
filter.lowpass(1000.0 / 44100.0, 0.7, BiquadDesign::Cookbook);
// Process a buffer of audio
let mut audio_buffer = vec![0.0; 1024];
// Fill buffer with audio data...
// Apply the filter
filter.process_buffer(&mut audio_buffer);
}
use signalsmith_dsp::delay::{Delay, InterpolatorCubic};
fn delay_example() {
// Create a delay line with cubic interpolation and 1 second capacity at 44.1 kHz
let mut delay = Delay::new(InterpolatorCubic::<f32>::new(), 44100);
// Process audio
let mut output = 0.0;
for _ in 0..1000 {
let input = 0.5; // Replace with your input sample
// Read from the delay line (500 ms delay)
output = delay.read(22050.0);
// Write to the delay line
delay.write(input);
// Use output...
}
}
use signalsmith_dsp::stretch::SignalsmithStretch;
fn time_stretch_example() {
// Create a new stretch processor
let mut stretcher = SignalsmithStretch::<f32>::new();
// Configure for 2x time stretching with pitch shift up 3 semitones
stretcher.configure(1, 1024, 256, false); // 1 channel, 1024 block size, 256 interval
stretcher.set_transpose_semitones(3.0, 0.5); // Pitch up 3 semitones
stretcher.set_formant_semitones(1.0, false); // Formant shift
// Input and output buffers
let input_len = 1024;
let output_len = 2048; // 2x longer output
let input = vec![vec![0.0; input_len]]; // Fill with audio data
let mut output = vec![vec![0.0; output_len]];
// Process the audio
stretcher.process(&input, input_len, &mut output, output_len);
}
use signalsmith_dsp::mix::{Hadamard, StereoMultiMixer};
fn mixing_example() {
// Create a Hadamard matrix for 4-channel mixing
let hadamard = Hadamard::<f32>::new(4);
// Mix 4 channels in-place
let mut data = vec![1.0, 2.0, 3.0, 4.0];
hadamard.in_place(&mut data);
// data now contains orthogonal mix of input channels
// Create a stereo-to-multichannel mixer (must be even number of channels)
let mixer = StereoMultiMixer::<f32>::new(6);
// Convert stereo to 6 channels
let stereo_input = [0.5, 0.8];
let mut multi_output = vec![0.0; 6];
mixer.stereo_to_multi(&stereo_input, &mut multi_output);
// Convert back to stereo
let mut stereo_output = [0.0, 0.0];
mixer.multi_to_stereo(&multi_output, &mut stereo_output);
// Apply energy-preserving crossfade
let mut to_coeff = 0.0;
let mut from_coeff = 0.0;
signalsmith_dsp::mix::cheap_energy_crossfade(0.3, &mut to_coeff, &mut from_coeff);
// Use coefficients for crossfading between signals
}
use signalsmith_dsp::spacing::{Spacing, Position};
fn spacing_example() {
// Create a new Spacing effect with a given sample rate
let mut spacing = Spacing::<f32>::new(48000.0);
// Add source and receiver positions (in meters)
let src = spacing.add_source(Position { x: 0.0, y: 0.0, z: 0.0 });
let recv = spacing.add_receiver(Position { x: 3.43, y: 0.0, z: 0.0 });
// Add a direct path
spacing.add_path(src, recv, 1.0, 0.0);
// Prepare input and output buffers
let mut input = vec![0.0; 500];
input[0] = 1.0; // Impulse
let mut outputs = vec![vec![0.0; 500]];
// Process the input through the effect
spacing.process(&[&input], &mut outputs);
// outputs[0] now contains the processed signal
}
For more advanced usage examples, see the examples directory:
- FFT Example - Fast Fourier Transform
- Filter Example - Biquad filters
- Delay Example - Delay lines
- STFT Example - Short-time Fourier transform
- Stretch Example - Time stretching and pitch shifting
- Curves Example - Curve interpolation
- Envelopes Example - LFOs and envelope generators
- Linear Example - Linear operations
- Mix Example - Audio mixing utilities
- Performance Example - Performance optimizations
- Rates Example - Sample rate conversion
- Spectral Example - Spectral processing
- Windows Example - Window functions
Provides Fast Fourier Transform implementations optimized for different use cases:
SimpleFFT
: General purpose complex-to-complex FFTSimpleRealFFT
: Optimized for real-valued inputs- Support for non-power-of-2 sizes (factorizable into 2^a × 3^b)
Digital filter implementations:
Biquad
: Second-order filter section with various design methods- Various filter types: lowpass, highpass, bandpass, notch, peaking, etc.
- Support for filter cascading and multi-channel processing
Delay line utilities:
- Various interpolation methods (nearest, linear, cubic)
- Single and multi-channel delay lines
- Buffer abstractions for efficient memory usage
Frequency-domain processing tools:
- Magnitude/phase conversion utilities
- Phase vocoder techniques for pitch and time manipulation
- Frequency-domain filtering and manipulation
Short-time Fourier transform processing:
- Overlap-add processing framework
- Window function application
- Spectral processing utilities
Time stretching and pitch shifting:
- High-quality phase vocoder implementation using
SignalsmithStretch
- Independent control of time and pitch
- Formant preservation and frequency mapping
- Real-time processing capabilities
Multichannel mixing utilities:
- Orthogonal matrices (Hadamard, Householder) for efficient mixing
- Stereo to multichannel conversion
- Energy-preserving crossfading
Window functions for spectral processing:
- Common window types (Hann, Hamming, Kaiser, etc.)
- Window design utilities
- Overlap handling and perfect reconstruction
Low-frequency oscillators and envelope generators:
- Precise control with minimal aliasing
- Multiple waveform types
- Configurable frequency and amplitude
Linear algebra utilities:
- Expression template system for efficient vector operations
- Optimized mathematical operations
Curve interpolation:
- Cubic curve interpolation with control over slope and curvature
- Smooth parameter transitions
Sample rate conversion:
- High-quality resampling algorithms
- Configurable quality settings
Provides a customizable room reverb effect:
- Multi-tap delay network simulating early reflections
- 3D source and receiver positioning
- Adjustable room size, damping, diffusion, bass, decay, and cross-mix
- Suitable for spatial audio and immersive effects
std
(default): Use the Rust standard libraryalloc
: Enable allocation without std (for no_std environments)
This library is designed with performance in mind and offers several optimizations:
- SIMD Opportunities: Code structure allows for SIMD optimizations where applicable
- Cache-Friendly Algorithms: Algorithms are designed to minimize cache misses
- Minimal Allocations: Operations avoid allocations during processing
- Trade-offs: Where appropriate, there are options to trade between quality and performance
For maximum performance:
- Use the largest practical buffer sizes for batch processing
- Reuse processor instances rather than creating new ones
- Consider using the
f32
type for most audio applications unless higher precision is needed - Review the examples in
examples/perf_example.rs
for performance-critical applications
This project is licensed under the MIT License - see the LICENSE file for details.
- Original C++ library: Signalsmith Audio DSP Library
- Signalsmith Audio's excellent technical blog with in-depth explanations of DSP concepts
- The comprehensive design documentation for the time stretching algorithm