| Crates.io | cute-dsp |
| lib.rs | cute-dsp |
| version | 0.0.40 |
| created_at | 2026-01-19 05:35:25.814492+00 |
| updated_at | 2026-01-20 06:15:06.781095+00 |
| description | A Rust library for audio and signal processing |
| homepage | |
| repository | https://github.com/CuteDSP/RSCuteDSP |
| max_upload_size | |
| id | 2053794 |
| size | 546,895 |
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.
alloc featureAdd this to your Cargo.toml:
[dependencies]
cute-dsp = "0.0.2"
This library supports compilation to WebAssembly for use in web browsers and Node.js, with full DSP functionality exposed.
To build for WASM (no-modules target for broad compatibility):
Install wasm-pack:
cargo install wasm-pack
Build the WASM package:
wasm-pack build --target no-modules --out-dir pkg --features wasm
Use in HTML/JavaScript (no-modules target):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CuteDSP WASM Demo</title>
</head>
<body>
<script src="pkg/cute_dsp.js"></script>
<script>
async function run() {
// Initialize WASM
await wasm_bindgen();
// Create FFT instance
const fft = new wasm_bindgen.WasmFFT(1024);
// Create input arrays
const realIn = new Float32Array(1024);
const imagIn = new Float32Array(1024);
const realOut = new Float32Array(1024);
const imagOut = new Float32Array(1024);
// Fill input with a sine wave
for (let i = 0; i < 1024; i++) {
realIn[i] = Math.sin(2 * Math.PI * i / 1024);
imagIn[i] = 0;
}
// Perform FFT
fft.fft_forward(realIn, imagIn, realOut, imagOut);
// Create and use a biquad filter
const filter = new wasm_bindgen.WasmBiquad();
filter.lowpass(0.1, 0.7); // Normalized frequency, Q factor
const audioIn = new Float32Array(1024);
const audioOut = new Float32Array(1024);
// Fill audioIn with audio data...
filter.process(audioIn, audioOut);
// Create a delay line
const delay = new wasm_bindgen.WasmDelay(44100); // Max delay samples
const delayedSample = delay.process(0.5, 22050.0); // Input sample, delay in samples
// Create an LFO
const lfo = new wasm_bindgen.WasmLFO();
lfo.set_params(0.0, 1.0, 5.0, 0.0, 0.0); // low, high, rate, rate_variation, depth_variation
const lfoSample = lfo.process();
// Create window functions
const kaiser = new wasm_bindgen.WasmKaiser(0.1); // Beta parameter
const windowData = new Float32Array(512);
kaiser.fill(windowData);
// Hann and Hamming windows
wasm_bindgen.WasmHann.fill(windowData);
wasm_bindgen.WasmHamming.fill(windowData);
// Create a delay line
const delay = new wasm_bindgen.WasmDelay(44100); // Max delay samples
const delayedSample = delay.process(0.5, 22050.0); // Input sample, delay in samples
// Create an LFO
const lfo = new wasm_bindgen.WasmLFO();
lfo.set_params(0.0, 1.0, 5.0, 0.0, 0.0); // low, high, rate, rate_variation, depth_variation
const lfoSample = lfo.process();
// Create window functions
const kaiser = new wasm_bindgen.WasmKaiser(0.1); // Beta parameter
const windowData = new Float32Array(512);
kaiser.fill(windowData);
// Hann and Hamming windows
wasm_bindgen.WasmHann.fill(windowData);
wasm_bindgen.WasmHamming.fill(windowData);
// Create STFT
const stft = new wasm_bindgen.WasmSTFT(false); // false for non-modified
stft.configure(1, 1, 512); // input channels, output channels, block size
// Linear curve mapping
const curve = wasm_bindgen.WasmLinearCurve.from_points(0.0, 1.0, 0.0, 100.0);
const mappedValue = curve.evaluate(0.5);
// Sample rate conversion filters
const srcFilter = new Float32Array(256);
wasm_bindgen.WasmSampleRateConverter.fill_kaiser_sinc_filter(srcFilter, 0.45, 0.55);
// Spectral utilities
const complex = wasm_bindgen.WasmSpectralUtils.mag_phase_to_complex(1.0, 0.5);
const magPhase = wasm_bindgen.WasmSpectralUtils.complex_to_mag_phase(1.0, 0.0);
const dbValue = wasm_bindgen.WasmSpectralUtils.linear_to_db(10.0);
// Multi-channel mixing
const hadamard = new wasm_bindgen.WasmHadamardMixer(4); // 4-channel mixer
const channels = new Float32Array([1.0, 0.5, 0.3, 0.1]);
hadamard.mix_in_place(channels);
console.log('DSP operations completed!');
}
run();
</script>
</body>
</html>
Or try the included real-time demo: wasm_demo.html
use cute_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 cute_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 cute_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 cute_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 cute_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;
cute_dsp::mix::cheap_energy_crossfade(0.3, &mut to_coeff, &mut from_coeff);
// Use coefficients for crossfading between signals
}
use cute_dsp::envelopes::Adsr;
fn adsr_example() {
// Create ADSR with 44.1kHz sample rate
let mut adsr = Adsr::new(44100.0);
// Set parameters: attack, decay, sustain, release (in seconds)
adsr.set_times(0.01, 0.1, 0.7, 0.2);
// Note on (start attack)
adsr.gate(true);
// Generate envelope samples
for _ in 0..44100 {
let envelope_value = adsr.next();
// Use envelope_value to modulate audio signal
}
// Note off (start release)
adsr.gate(false);
// Continue generating samples during release
for _ in 0..8820 {
let envelope_value = adsr.next();
}
}
For WebAssembly usage, see ADSR_WASM.md for complete browser integration examples.
use cute_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 module)Provides Fast Fourier Transform implementations optimized for different use cases:
SimpleFFT: General purpose complex-to-complex FFTSimpleRealFFT: Optimized for real-valued inputsfilters module)Digital filter implementations:
Biquad: Second-order filter section with various design methodsdelay module)Delay line utilities:
spectral module)Frequency-domain processing tools:
stft module)Short-time Fourier transform processing:
stretch module)Time stretching and pitch shifting:
SignalsmithStretchmix module)Multichannel mixing utilities:
windows module)Window functions for spectral processing:
envelopes module)Low-frequency oscillators and envelope generators:
linear module)Linear algebra utilities:
curves module)Curve interpolation:
rates module)Sample rate conversion:
spacing module)Provides a customizable room reverb effect:
std (default): Use the Rust standard libraryalloc: Enable allocation without std (for no_std environments)wasm: Enable WebAssembly bindingsRun the standard test suite:
cargo test
The project includes comprehensive WASM tests using wasm-bindgen-test:
Node.js Tests (recommended):
# Build for Node.js
wasm-pack build --target nodejs --out-dir pkg --dev -- --features wasm
# Run tests
node test-adsr-wasm.js
Browser Tests:
wasm-pack test --headless --chrome --features wasm
See ADSR_WASM_TESTING.md for complete testing documentation.
This library is designed with performance in mind and offers several optimizations:
For maximum performance:
f32 type for most audio applications unless higher precision is neededexamples/perf_example.rs for performance-critical applicationsThis project is licensed under the MIT License - see the LICENSE file for details.