FreeDSP

Get the app
engine—
rate—
latency—
dc—
in—
out—
Press Start listening to open the input stream.
Microphone or Line Microphones, keyboards, synths, drum machines, a phone or anything with a line or headphone output, active guitars and basses (with a battery). Also any instrument through an audio interface’s instrument input. Magnetic pickup Electric guitar, electric bass, lap steel, electric piano (Rhodes, Wurlitzer): a passive pickup plugged straight into a microphone input. Piezo pickup Acoustic guitar, violin, cello, ukulele, mandolin with an under-bridge pickup, or a contact mic, plugged straight into a microphone input.
0.0 dB

Signal chain

0 effects
Nothing in the chain yet. Add an effect below, then open it to edit the formula — or paste a whole chain into Edit as text.
Drag ⣿ to reorder. Double-click a slider to reset it.
Formula reference

How a plugin works

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.

Directives

  • #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.

Built-in values

  • x input sample, −1…1
  • t seconds, n sample count
  • sr sample rate, ch channel (0 = left)
  • pi, e

Functions

sin cos tan tanh atan exp log sqrt abs sign floor ceil round min max pow mod clamp noise bshift pshift psola pitch vocoder

Delay lines

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.

Echo with feedback: d = delay(time*sr) then dw(x + d*fb) then x + d*mix.

Pitch

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 8 ms in the middle of the guitar (about 24 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. Two calls on x with the same bands share their filters. Not inside ?:.

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 ?:.

Operators

+ - * / % ^   < > <= >= == !=   && || !   cond ? a : b

Feedback and DC

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.

Limits

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.

Effect reference
Glossary