Files
soundcraft/crates/dsp/tests/fuzz.rs
Brandon ThomasandClaude Opus 5.5 755f02fc85 Foundation: time, audio-io, midi, dsp, model, mix, engine, playback crates
Workspace for SoundCraft, a clean-room pure-Rust Pro Tools-class DAW:
timebases and tempo maps, WAV/AIFF/FLAC/symphonia audio IO with peaks,
SMF and MIDI ops, 26 original DSP plugins, the session model, the mix
engine, ~180 registered commands with undo, a cpal player, and the
agent rules (AGENTS.md, ATTRIBUTION.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 22:27:29 -04:00

57 lines
2.2 KiB
Rust

use proptest::prelude::*;
use soundcraft_dsp::{create, offline, plugins};
proptest! {
#![proptest_config(ProptestConfig::with_cases(48))]
/// Any parameter values and any finite input: no panic, finite output.
#[test]
fn plugins_survive_random_params(
which in 0usize..64,
values in proptest::collection::vec(any::<f32>(), 32),
input in proptest::collection::vec(-4.0f32..4.0, 1..700),
block in 1usize..300,
) {
let info = plugins()[which % plugins().len()];
let mut p = create(info.id).unwrap();
p.prepare(44_100.0, block, 2);
for (param, v) in info.params.iter().zip(values.iter().cycle()) {
p.set_param(param.id, *v);
}
p.note_on(0, 60, 100);
let mut io = [input.clone(), input.clone()];
let len = input.len();
let mut pos = 0;
while pos < len {
let n = block.min(len - pos);
let mut buf = vec![io[0][pos..pos + n].to_vec(), io[1][pos..pos + n].to_vec()];
p.process(&mut buf, n);
io[0][pos..pos + n].copy_from_slice(&buf[0]);
io[1][pos..pos + n].copy_from_slice(&buf[1]);
pos += n;
}
prop_assert!(io.iter().flatten().all(|v| v.is_finite()), "{} produced non-finite output", info.id);
}
/// Offline helpers accept any arguments without panicking.
#[test]
fn offline_survives_random_args(
data in proptest::collection::vec(any::<f32>(), 0..400),
a in any::<f32>(),
n in 0usize..1000,
r in any::<f64>(),
) {
let ch = vec![data.clone(), data];
let _ = offline::non_silent_ranges(&ch, a, n, n, n);
let _ = offline::detect_transients(&ch, a, a);
let _ = offline::time_stretch(&ch, r, a);
let _ = offline::pitch_shift(&ch, a, a);
let _ = offline::resample(&ch, n as u32, (n as u32).wrapping_mul(3) % 200_000);
let mut m = ch.clone();
offline::normalize(&mut m, a, n % 2 == 0);
offline::fade(&mut m, n, n / 2, offline::FadeShape::SCurve);
offline::gain(&mut m, a);
let _ = soundcraft_dsp::spectrum::magnitude_db(&ch[0], n);
}
}