mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-26 11:36:51 -06:00
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>
57 lines
2.2 KiB
Rust
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);
|
|
}
|
|
}
|