35 releases (7 breaking)
Uses new Rust 2024
| new 0.57.1 | Jun 8, 2026 |
|---|---|
| 0.56.0 | Jun 6, 2026 |
#6 in #truce
21 downloads per month
Used in 2 crates
45KB
642 lines
truce-driver
Headless driver for truce plugins.
Overview
Instantiate a plugin, feed it scripted audio + events for a fixed duration, capture the output - no DAW, no format wrapper, no GUI. Three consumers in-tree:
truce-test- assertion helpers (assert_state_round_trip,assert_nonzero, thedriver!macro) layered on top of the capturedDriverResult.truce-standalone's offline-render path -cargo truce run --no-playbackparses CLI flags into anInputSource::Buffer+Script, runsPluginDriver, writes the captured audio out as WAV.- Plugin authors writing custom
main.rsbinaries - batch CI renders, demo audio generation, preset-rendering pipelines.
Key types
PluginDriver<P>- the builder. Carries sample rate, block size, channel count, the input source, the script, the transport state, and the capture spec.InputSource-Silence/Constant/Buffer(Vec<Vec<f32>>)/Generator(Box<dyn FnMut(usize, f64) -> f32>).Script- sample-accurate sequence ofEventBodys with a cursor (note_on,note_off,set_param,wait_ms, ...).CaptureSpec- what to capture per block (audio, output events, meters, param snapshots).DriverResult- the post-run capture, indexable by channel.
Precision
PluginDriver routes through RawBufferScratch<P::Sample> - the
same widening/narrowing path the format wrappers use - so
prelude64 plugins can be driven in headless tests with the
wrapper-boundary conversion done internally. The driver's public
input / output buffers are always f32 (host-wire); the plugin's
process() sees AudioBuffer<P::Sample>.
Example
use std::time::Duration;
use truce_driver::{InputSource, PluginDriver};
let result = PluginDriver::<MyPlugin>::new()
.sample_rate(48_000.0)
.duration(Duration::from_secs(2))
.input(InputSource::Constant(0.5))
.set_param(MyParamId::Gain, 0.7)
.script(|s| {
s.note_on(60, 0.8);
s.wait_ms(500);
s.note_off(60);
})
.run();
Dependencies
~480KB