Skip to main content

Module sfx

Module sfx 

Source
Expand description

A parametric sound-effect generator in the style of the synth module. Requires the sfx feature, which enables synth.

An Effect is a small set of numbers: a waveform, a pitch with slides, vibrato and an arpeggio step, an envelope with punch, a duty sweep, swept low- and high-pass filters, a repeat period and a volume. It renders deterministically into mono Audio, reads and writes a short text form, and can be drawn from a seed by a Preset.

use audiobox::sfx::{Effect, Preset};
let coin: Effect = "wave=pulse duty=50 frequency=1046.5 sustain=0.04 punch=0.5
                    decay=0.25 arpeggio=5 arpeggio-time=0.06".parse()?;
let audio = coin.render(44_100)?;
assert_eq!(audio.frames(), 12_789);

// Try seeds until one sounds right, then keep its text.
let jump = Effect::preset(Preset::Jump, 7);
assert_eq!(jump.to_string().parse::<Effect>()?, jump);

§Parameters and text form

The text form is whitespace-separated key=value pairs, in any order, on one line or several; ; starts a comment that runs to the end of the line. Missing keys keep their defaults. Effect’s Display writes the same form, and parsing it gives back an equal effect: numbers are written in Rust’s shortest form that reads back to the same f64.

KeyFieldUnitRangeDefault
wavewaveformpulse, triangle, saw, noisepulse
dutywaveformpulse duty in percent12.5, 25, 50, 7550
noisewaveformnoise modelong, shortlong
frequencyfrequencyHz10..=20000440
slideslideoctaves per second-64..=640
slide-changeslide_changeoctaves per second, per second-256..=2560
vibrato-depthvibrato_depthsemitones0..=240
vibrato-speedvibrato_speedHz0..=1000
attackattackseconds0..=100
sustainsustainseconds0..=100.1
punchpunchextra level at the start of the sustain0..=10
decaydecayseconds0..=100.2
duty-sweepduty_sweepduty change per second (pulse only)-10..=100
low-passlow_passcutoff in Hz, 0 for off0 or 10..=200000
low-pass-sweeplow_pass_sweepoctaves per second-16..=160
high-passhigh_passcutoff in Hz, 0 for off0 or 10..=200000
high-pass-sweephigh_pass_sweepoctaves per second-16..=160
arpeggioarpeggiosemitones-48..=480
arpeggio-timearpeggio_timeseconds0..=100
repeatrepeatseconds, 0 for off0 or 0.01..=100
volumevolumelinear0..=10.5

attack + sustain + decay is the effect’s duration. It must be more than 0 and at most MAX_DURATION seconds. Values out of range, and duty or duty-sweep without a pulse or noise without noise, are rejected with ErrorCode::InvalidArgument; in text, the error is a ParseError with the line and column of the value.

§Sound

At time t seconds since the start, or since the last repeat, the frequency is frequency × 2^(slide·t + slide_change·t²/2), raised by arpeggio semitones once t ≥ arpeggio_time, and modulated by a vibrato of vibrato_depth semitones at vibrato_speed Hz. It is limited to 0..=sample_rate / 2. The pulse duty starts at duty and changes by duty_sweep per second, limited to 1..=99%. Noise uses the synthesizer’s shift register, clocked at 93 times the frequency.

repeat restarts the pitch, slides, arpeggio and duty every repeat seconds; the envelope, the vibrato and the filters continue.

The envelope rises linearly from 0 to 1 over attack, then holds for sustain starting at 1 + punch and falling linearly to 1, then falls linearly to 0 over decay. Each stage is rounded to whole samples, so an effect lasts round(attack·rate) + round(sustain·rate) + round(decay·rate) frames. The output is the filtered oscillator times the envelope times volume, so it peaks at volume × (1 + punch).

Both filters are 2-pole (12 dB per octave) Butterworth state-variable filters: the low-pass passes frequencies below its cutoff and the high-pass those above, and each attenuates its cutoff by 3 dB. A sweep moves a cutoff by that many octaves per second from the start of the effect, within 10 Hz..=0.45 × the sample rate.

Like the synthesizer, rendering uses only basic IEEE arithmetic and the crate’s own series for 2^x, sine and tangent, so an effect gives the same samples on every platform.

Re-exports§

pub use crate::synth::ParseError;

Structs§

Effect
The parameters of a sound effect. See the module documentation for their units, ranges and meaning.

Enums§

Preset
Kinds of effect that Effect::preset draws from a seed.

Constants§

MAX_DURATION
The longest effect, in seconds.