Alarms, sirens and wobbly retro sounds need a volume or a pitch that
swings. Two new nodes do that, on a voice and on a bus alike.
- Tremolo: Rate (0 to 20 Hz), Depth (0 to 100 %), Shape (Sine,
Triangle, Square, Saw). The volume swings between full and
1 - depth.
- Vibrato: Rate (0.5 to 20 Hz), Depth (0 to 4 semitones), Shape. The
shape is the curve of the pitch, a Square jumps between two pitches.
- As the issue decided: two nodes, phase 0 on the first sample of the
voice, no fade-in time. Both run on the FX worklet, the classes are
in lfo.ts and tested in Node.
- Deviation from the issue text, as in the plan: the Vibrato is a delay
that swings, not playbackRate. A bus has no playbackRate, and the
sound keeps its length.
- The delay swings around a center taken from the start values. The
center counts as the latency of the node, so a voice starts that
much earlier and a Mix and a bus make up for it.
- Known limit, in the node text and the wiki: a depth turned up or a
rate turned down after the start asks for a delay below 0. The lower
half of the swing then flattens.
Finding: the first e2e run was red at the edge of a window. The phase
is summed up, so the square flips one sample later than 2400 steps of
10/48000 suggest. The check keeps 10 samples away from the edges.
Tests:
- Unit lfo (new) 5, soundfx 53 (2 new), sound-library 102 (1 new),
green.
- Counter-checks, each turns one test red: the swing turned over (up
and down swapped), the start time not passed to the worklet.
- e2e 34 (melektaus-atx): ALL PASSED, 80 checks (1 new). Chrome
offline: Tremolo square silent before its voice, then 0.5 and 0 for
50 ms each. Vibrato square at 5 Hz, 1 semitone: 1059.5 Hz and
940.5 Hz.
- The gate runs once on the last commit of this series.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>