Delay example entry point
examples/tutorials/src/bin/effect.rs · 34 source lines
Read the chapters in source order. Select a numbered source line to expand its explanation; the line numbers and code match this snapshot exactly.
cargo run -p ravet-examples --bin effect --locked -- --render target/examples/effect-guide.wavChapters
Imports and the offline helper
This executable selects a live delay window by default. The shared support module supplies explicit file-path parsing, block rendering and WAV writing. DelayProcessor owns signal state; foundation types carry timed parameter edits.
1//! Live stereo delay, or an explicit hardware-free impulse/automation render.
Source note: Live stereo delay, or an explicit hardware-free impulse/automation render.
Link to line 12#[path = "../support/mod.rs"]
Apply this Rust attribute to the following item. cfg selects which target/feature/test build contains it; derive generates the named trait implementations.
Link to line 23mod support;
Bring these module/type names into scope for “Imports and the offline helper”; the surrounding chapter explains their responsibilities.
Link to line 34use ravet_examples::delay::DelayProcessor;
Bring these module/type names into scope for “Imports and the offline helper”; the surrounding chapter explains their responsibilities.
Link to line 45use ravet_foundation::{Event, EventData, ParameterId};
Bring these module/type names into scope for “Imports and the offline helper”; the surrounding chapter explains their responsibilities.
Link to line 56
Blank line separating the surrounding statements.
Link to line 6Construct a parameter event
Wrap a physical value and stable parameter ID in EventData::ParameterValue. frame_offset is an absolute clip position here; support::render will translate it into a block-local offset. This helper does not change a processor by itself.
7fn parameter(frame_offset: usize, id: ParameterId, value: f32) -> Event {
Define parameter. Wrap a physical value and stable parameter ID in EventData::ParameterValue. frame_offset is an absolute clip position here; support::render will translate it into a block-local offset. This helper does not change a processor by itself.
Link to line 78 Event {
Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Construct a parameter event” explanation above.
Link to line 89 frame_offset,
Supply these names as the remaining imports, arguments or fields of the surrounding declaration.
Link to line 910 data: EventData::ParameterValue { id, value },
Typed event payload; timing is kept separately in frame_offset.
Link to line 1011 }
Close the surrounding scope, value or argument list in “Construct a parameter event”.
Link to line 1112}
Close the surrounding scope, value or argument list in “Construct a parameter event”.
Link to line 1213
Blank line separating the surrounding statements.
Link to line 13Choose live UI or rendering
Only an initial --render argument selects the hardware-free path. Otherwise launch("effect") opens the interactive example. Parse the output path through the helper, which rejects extra arguments and requires explicit rendering.
14fn main() -> support::Result<()> {
Define main. Only an initial --render argument selects the hardware-free path. Otherwise launch("effect") opens the interactive example. Parse the output path through the helper, which rejects extra arguments and requires explicit rendering.
Link to line 1415 if !std::env::args_os().nth(1).is_some_and(|a| a == "--render") {
Evaluate this condition or visit this range in source order. The statements in the following scope implement “Choose live UI or rendering”.
Link to line 1516 return ravet_examples::launch("effect");
Return this result to the caller; the remaining statements in the function are skipped.
Link to line 1617 }
Close the surrounding scope, value or argument list in “Choose live UI or rendering”.
Link to line 1718 let path = support::output_path("target/examples/effect.wav")?;
Bind path to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.
Link to line 18Create the stereo impulse fixture
Two seconds at the 48 kHz helper rate gives 96,000 samples per channel. Place a 0.5 left impulse at frame 0, a 0.25 right impulse at frame 2,400 (50 ms), and a 0.125 left dry impulse at frame 73,600.
19 let frames = 2 * support::SAMPLE_RATE;
Bind frames to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.
Link to line 1920 let mut input = [vec![0.; frames], vec![0.; frames]];
Bind mutable input to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.
Link to line 2021 input[0][0] = 0.5;
Assign the computed value to input[0][0]. The right-hand expression supplies the new value for this step.
Link to line 2122 input[1][2400] = 0.25;
Assign the computed value to input[1][2400]. The right-hand expression supplies the new value for this step.
Link to line 2223 input[0][73_600] = 0.125; // dry impulse after sample-timed bypass
Place a later left-channel impulse after bypass has become active, so the rendered clip can verify its exact dry level.
Link to line 23Schedule exact automation
Parameter 2 changes feedback to 0.25 at frame 60,013, deliberately inside a 256-frame block. Parameter 4 switches dry bypass on at frame 72,007. The preceding helper keeps the supplied same-frame order.
24 let events = [
Bind events to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.
Link to line 2425 parameter(60_013, ParameterId(2), 0.25), // inside a 256-frame block
Change delay feedback (ID 2) to 0.25 at absolute frame 60,013, which intentionally lies inside a 256-frame render block.
Link to line 2526 parameter(72_007, ParameterId(4), 1.), // dry from this exact sample
Switch dry bypass (ID 4) on at frame 72,007. Events apply before the sample at their offset.
Link to line 2627 ];
Close the surrounding scope, value or argument list in “Schedule exact automation”.
Link to line 27Prepare, render and write
Set the complete delay patch in its documented array order: 250 ms, feedback 0.5, fully wet, bypass off, ping-pong on. Render into the provided stereo storage, then write PCM16 through the worker-side WAV helper. Rendering/writing errors propagate with ?. The final messages describe the fixture, not a live device measurement.
28 let mut delay = DelayProcessor::default();
Bind mutable delay to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.
Link to line 2829 delay.set_controls([250., 0.5, 1., 0., 1.])?;
Request 250 ms delay, feedback 0.5, fully wet output, bypass off and ping-pong on, in the delay’s five-value physical order.
Link to line 2930 let audio = support::render(&mut delay, Some(input), frames, &events)?;
Bind audio to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.
Link to line 3031 support::write_wave(&path, &audio)?;
The ? operator returns an error immediately on failure and unwraps the success value for the next step.
Link to line 3132 println!("250 ms ping-pong delay; feedback 0.5 -> 0.25 with 5 ms smoothing, then dry bypass.");
Report this explicit fixture result to stdout; printing belongs to the offline/control path, not the audio callback.
Link to line 3233 Ok(())
Report successful completion without returning a payload.
Link to line 3334}
Close the surrounding scope, value or argument list in “Prepare, render and write”.
Link to line 34