A rig does all the work. Add one to start.
code is a list of lines. Open a saved workspace, or paste one copied from another browser or device, to take it over; the rigs and their sounds change at once. Save and Share keep the workspace as it plays.
One statement per line. The value of the last line becomes the output sample. The code runs once per sample, per channel.
Any name you haven't declared as a parameter is state: it keeps its value into the next sample and starts at 0. That is how you write filters and envelopes.
Lines starting with # are directives, // is a comment.
#name My effect#param drive 4 1 40 — name, start, min, max. Becomes a slider.#param steps 4 1 8 1 — a fifth number makes it move in steps and jump instead of glide.#param scale 0 0 2 1 chromatic major minor — words after the step name each position; _ shows as a space.x input sample, −1…1t seconds, n sample countsr sample rate, ch channel (0 = left)pi, elat the round trip in samples: mic to ear, the latency readout's total (the Looper uses it to stay on the beat)sin cos tan tanh atan exp log sqrt abs sign floor ceil round min max pow mod clamp noise bshift pshift psola pitch vocoder
Four per effect, up to 2 seconds, fractionally interpolated. dw(v) writes, delay(n) reads n samples back. Lines 2–4 use dw2 delay2 … dw4 delay4. dw(v, 30) makes that line 30 seconds long (up to 60, a plain number), as the Looper does.
Echo with feedback: d = delay(time*sr) then dw(x + d*fb) then x + d*mix.
bshift(x, ratio, bands) — the low-latency pitch shifter: ratio 0.25…4; 2 is an octave up, pow(2, st/12) converts semitones. It follows within about 10 ms in the middle of the guitar (about 26 ms on a low E), because it works on a bank of filters instead of a window. bands per octave is a plain number from 6 to 48, default 24: more holds chords together, 16 is a little quicker and lighter on single notes. An optional fourth number, 4, gives every band four poles instead of two: bshift(x, r, 48, 4) is much cleaner (about as clean as pshift at 85 ms) for about 10 ms more delay and twice the CPU. Two calls on x with the same bands and poles share their filters. Not inside ?:, except to choose between calls, as the presets' quality switch does.
pshift(x, ratio, ms) — the most accurate pitch shifter, with a delay: ratio 0.25…4; 2 is an octave up, pow(2, st/12) converts semitones. ms is the analysis window, a plain number, default 85. It is also how late the shifted signal arrives, and the latency readout includes it. Longer holds chords together, shorter reacts faster. Call it on every sample, not inside ?:.
pitch(x, ms) — the detected pitch of x in Hz, 0 when nothing periodic is playing. Window default 43 ms (lowest note about 50 Hz); 85 reaches a bass's low E. Updates every quarter window, adds no delay to the signal. Same rule: not inside ?:.
psola(x, ratio, lowest) — a pitch shifter for one voice or single notes. It keeps a voice sounding like the same person (no chipmunk), and its delay is set by the lowest note it has to follow: lowest in Hz, a plain number, default 75, gives 27 ms; 150 gives 13 ms. On chords, or for big jumps on an instrument, use bshift. Not inside ?:.
vocoder(voice, carrier, bands) — gives carrier (any sound you make in the formula, usually a synth) the changing tone of voice, so the synth seems to talk. bands is a plain number from 8 to 32, default 20: more is clearer, fewer more robotic. No added delay. Not inside ?:.
+ - * / % ^ < > <= >= == != && || ! cond ? a : b
Any recirculating loop has a DC gain of 1/(1−g), so a small standing offset grows until it eats the headroom. DC block handles the input; inside your own loop, subtract it first: s = x - px + 0.997*s then px = x.
Each channel is processed on its own, so an effect can't mix left into right. Use ch to make the two sides behave differently.
Parameters glide over about 10 ms when you move a slider, so sweeps don't click.
#name starts a new effect; slider positions travel with the text as the #param start value; #off under a name bypasses that effect.
Pick your instrument and type a song, an artist or a sound. The effects are set up for you, with a preset for each part of the song. Only what you type and the instrument you pick go to our server and an AI; your sound never leaves this device.
Write your own:
The app will ask whether to let this device in, and shows it by this name.
The app also unlocks this browser: no time limit, no effect limit.
Open realtimeaudio.app/unlock in the browser and type this code, or scan it with a phone.
Getting a code…
NowDSP for Raspberry Pi and Linux needs the licence key from your purchase email. Paste it here once: it stays on this computer.