math-dsp
DSP utilities for audio signal generation and FFT-based analysis.
Library name: math_audio_dsp
Version: 0.3.1
Overview
This crate provides two core modules:
signals-- Test signal generation (tones, sweeps, noise) with utility functions for fade, padding, and channel manipulationanalysis-- FFT-based frequency analysis including spectrum computation (Welch's method and single-FFT), acoustic metrics (RT60, clarity C50/C80, THD), microphone compensation, and CSV I/O
Signal Generation
Generate common test signals as Vec<f32>:
| Function | Description |
|---|---|
gen_tone(freq, amp, sample_rate, duration) |
Pure sine wave |
gen_two_tone(f1, a1, f2, a2, sample_rate, duration) |
Sum of two sines (IMD testing), auto-normalized to prevent clipping |
gen_log_sweep(f_start, f_end, amp, sample_rate, duration) |
Logarithmic frequency sweep for frequency response measurements |
gen_white_noise(amp, sample_rate, duration) |
Flat spectrum noise (deterministic LCG) |
gen_pink_noise(amp, sample_rate, duration) |
1/f spectrum noise (Voss-McCartney / Paul Kellett) |
gen_m_noise(amp, sample_rate, duration) |
ITU-R 468 weighted noise (emphasis around 6.3 kHz) |
Signal Utilities
| Function | Description |
|---|---|
apply_fade_in(signal, fade_samples) |
Hann window fade-in (in-place) |
apply_fade_out(signal, fade_samples) |
Hann window fade-out (in-place) |
add_silence_padding(signal, pre, post) |
Silence padding before/after |
prepare_signal_for_playback(signal, sr, fade_ms, pad_ms) |
Fade + padding in one call |
prepare_signal_for_playback_channels(...) |
Same with optional mono-to-stereo |
mono_to_stereo(signal) |
Duplicate mono to both channels |
interleave_per_channel(channels) |
Interleave per-channel buffers into one |
replicate_mono(signal, channels) |
Copy mono to N channels (interleaved) |
clip(x) |
Clamp to +/- 0.999999 |
frames_for(duration, sample_rate) |
Sample count for a given duration |
Example
use signals;
// Generate a 1 kHz tone at 0.5 amplitude, 48 kHz, 2 seconds
let tone = gen_tone;
// Generate a 20-20k Hz log sweep
let sweep = gen_log_sweep;
// Prepare for playback with 20ms fade and 250ms silence padding
let ready = prepare_signal_for_playback;
Analysis
Standalone WAV Analysis
Analyze a WAV file or sample buffer and get frequency response (magnitude + phase) on a log-spaced frequency grid:
use ;
// Analyze a buffer
let config = default; // Welch's method, 2000 points, 20-20kHz
let result = analyze_wav_buffer?;
// result.frequencies, result.magnitude_db, result.phase_deg
// Analyze a WAV file directly
let result = analyze_wav_file?;
Pre-built configs for common use cases:
| Config | Method | Use case |
|---|---|---|
WavAnalysisConfig::default() |
Welch's (averaged periodograms) | Stationary signals (music, noise) |
WavAnalysisConfig::for_log_sweep() |
Single FFT + pink compensation | Log sweep measurements |
WavAnalysisConfig::for_impulse_response() |
Single FFT | Impulse response analysis |
Configuration fields: num_points, min_freq, max_freq, fft_size, overlap, single_fft, pink_compensation, no_window.
Recording Analysis (Reference vs Recorded)
Compare a recorded WAV against a known reference signal to extract the system's transfer function:
use analyze_recording;
let result = analyze_recording?;
The AnalysisResult includes:
| Field | Description |
|---|---|
frequencies, spl_db, phase_deg |
Frequency response (2000 log-spaced points, 20-20kHz) |
estimated_lag_samples |
Latency between reference and recording (FFT cross-correlation) |
impulse_response, impulse_time_ms |
Time-domain impulse response |
excess_group_delay_ms |
Excess group delay |
thd_percent |
Total Harmonic Distortion (Farina's method from log sweep IR) |
harmonic_distortion_db |
Per-harmonic distortion curves (H2-H5) |
rt60_ms |
RT60 reverberation time (T20 extrapolation, octave-band filtered) |
clarity_c50_db, clarity_c80_db |
Speech/music clarity metrics |
spectrogram_db |
Time-frequency spectrogram |
Acoustic Metrics
Available as standalone functions for custom impulse responses:
use *;
// Broadband RT60 (T20 extrapolation from Schroeder decay)
let rt60 = compute_rt60_broadband;
// Broadband clarity
let = compute_clarity_broadband;
// Frequency-dependent RT60 and clarity (octave-band filtered, interpolated)
let rt60_spectrum = compute_rt60_spectrum;
let = compute_clarity_spectrum;
// Spectrogram
let = compute_spectrogram;
// Group delay from phase data
let group_delay = compute_group_delay;
Microphone Compensation
Load calibration data and apply inverse compensation to measurements:
use MicrophoneCompensation;
// Load from CSV (freq_hz,spl_db) or TXT (space/tab-separated)
let mic = from_file?;
// Interpolate at a specific frequency
let deviation_db = mic.interpolate_at;
// Pre-compensate a sweep signal
let compensated = mic.apply_to_sweep;
Smoothing and CSV I/O
use *;
// Octave smoothing (f32 and f64 variants)
let smoothed = smooth_response_f32;
// Write/read analysis CSV
write_wav_analysis_csv?;
write_analysis_csv?;
let loaded = read_analysis_csv?;
Binary: wav2csv
CLI tool to analyze a WAV file and output frequency/SPL/phase as CSV.
# Default (Welch's method)
# Log sweep analysis
# Custom parameters
Options: --num-points, --min-freq, --max-freq, --fft-size, --overlap, --single-fft, --pink-compensation, --no-window, -o/--output.
Dependencies
| Crate | Purpose |
|---|---|
rustfft |
FFT computation |
num-complex |
Complex number types |
hound |
WAV file I/O |
math-iir-fir |
Biquad filters (bandpass for octave-band analysis) |
log |
Logging |
clap |
CLI argument parsing (for wav2csv) |
Testing
&&