Use this skill whenever the user asks for Faust DSP code, audio effects, synthesizers, signal processors, or any .dsp file. Triggers include: phaser, flanger, reverb, delay, compressor, oscillator, filter, synthesizer, audio plugin, JSFX, VST, LV2, CLAP, JACK, Daisy, embedded audio, "write this in Faust", or any audio DSP implementation request. Also use when converting pseudocode or mathematical signal processing descriptions into Faust. Do NOT use for general audio programming in C++/Python/JUCE; those are code tasks that do not require this skill.
설치
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
Use this skill whenever the user asks for Faust DSP code, audio effects, synthesizers, signal processors, or any .dsp file. Triggers include: phaser, flanger, reverb, delay, compressor, oscillator, filter, synthesizer, audio plugin, JSFX, VST, LV2, CLAP, JACK, Daisy, embedded audio, "write this in Faust", or any audio DSP implementation request. Also use when converting pseudocode or mathematical signal processing descriptions into Faust. Do NOT use for general audio programming in C++/Python/JUCE; those are code tasks that do not require this skill.
license
DeMoD Audio Systems internal reference
Faust DSP Code Generation
Philosophy: Math Before Code
Always design the signal processing mathematics before writing a single line of Faust.
The workflow is:
Identify the DSP concept — what physical/perceptual phenomenon are you modeling?
Write the transfer function or difference equation — in LaTeX/math notation
Verify stability — pole locations, DC gain, edge cases
Map math to Faust primitives — one primitive per mathematical operation
Compose with Faust's algebra — :, <:, :>, ~, par()
Add UI and metadata last
Never start with UI sliders. Never write feedback before writing the transfer function.
Faust Language Fundamentals
The Signal Model
Faust processes synchronous streams of samples. Every expression is a function from N input streams to M output streams. The sample rate is available as ma.SR (a float).
// These are equivalent ways to write "pass signal through unchanged"
process = _; // identity: 1 input → 1 output
process = _,_; // stereo identity: 2 inputs → 2 outputs
Core Composition Operators
Operator
Name
Meaning
A : B
Sequential
Output of A feeds input of B. Ports must match.
A , B
Parallel
A and B side by side. Inputs and outputs concatenated.
A <: B
Split
Duplicates A's outputs to feed B's inputs (fan-out).
A :> B
Merge
Sums A's outputs to feed B's inputs (fan-in / mix).
A ~ B
Recursive
B's output (delayed 1 sample) feeds back into A's input.
Critical: ~ always inserts exactly one sample delay in the feedback path. This makes all feedback causal. There is no way to create a zero-delay feedback loop in Faust — this is by design.
The par, seq, sum, prod Iterators
// 4 filters in parallel, index k ∈ {0,1,2,3}
par(k, 4, someFilter(float(k)))
// 4 filters in series
seq(k, 4, someFilter(float(k)))
// Sum 4 signals
sum(k, 4, osc(baseFreq * pow(2.0, float(k))))
// Product of 4 signals (rare but valid)
prod(k, 4, envelope(float(k)))
Always cast the loop index: float(k) — it is an integer literal inside par/seq/sum.
Arithmetic and Primitives
// All standard operators work sample-by-sample
x + y x - y x * y x / y x % y
// Power: use pow() or int exponentiation via ma library
pow(x, 2.0) // x²
x * x // also x²
// Comparisons return 0.0 or 1.0
x > y x < y x >= y x <= y x == y x != y
// Conditionals
select2(cond, whenFalse, whenTrue) // choose between two signals
select3(cond, a, b, c) // three-way selector
// Min/max
min(x, y) max(x, y)
// Type casting
int(x) float(x)
Unit Delay
x' // prime operator: delays x by exactly 1 sample
// equivalent to x : mem
// equivalent to x @ 1
Variable Delay
x @ n // delay x by n samples (integer, 0 to some max)
// n can be a signal — time-varying delay
// For fractional (sub-sample) delays, use de library:
de.fdelay(maxDelay, delaySignal) // 3rd-order Lagrange interpolation
de.sdelay(maxDelay, interp, d) // smooth delay with interpolation factor
Standard Library Reference
Always import("stdfaust.lib") — it loads all standard libraries under their prefixes.
import("stdfaust.lib");
// Now available: ma, si, fi, os, no, de, en, an, ba, pm, sp, ro, ve, dm, mi
si.smoo // 1-pole smoother (≈20ms), use on ALL UI parameters
si.smooth(c) // 1-pole smoother with explicit coefficient c
si.bus(n) // n parallel wires
si.block(n) // n parallel ground (silence) wires
fi — Filters (most important library)
fi.pole(b) // H(z) = 1/(1 − b·z⁻¹), causal 1-pole IIR
fi.zero(b) // H(z) = 1 − b·z⁻¹, 1-zero FIR
fi.tf1(b0,b1,a1) // Direct-form I, 1st order: H(z)=(b0+b1z⁻¹)/(1+a1z⁻¹)
fi.tf2(b0,b1,b2,a1,a2) // Direct-form II, 2nd order
fi.lowpass(n,fc) // Butterworth LP, n=order, fc=cutoff Hz
fi.highpass(n,fc) // Butterworth HP
fi.bandpass(n,fl,fu)// Butterworth BP
fi.peak_eq(gain,fc,Q) // Parametric EQ peak
fi.notch(fc,Q) // Notch filter
IMPORTANT: fi.tf1 and fi.tf2 support time-varying coefficients. The coefficients can be signals that change each sample. This is the correct way to implement swept filters. Do not use fi.lowpass for sweeping — it recomputes internally and may alias.
os — Oscillators
os.osc(freq) // sine oscillator (accurate, not cheap)
os.sawtooth(freq) // bandlimited sawtooth
os.square(freq) // bandlimited square
os.triangle(freq) // bandlimited triangle
os.phasor(freq) // raw phasor [0, 1) — best for custom waveforms
os.lf_sawpos(freq) // low-frequency sawtooth [0, 1), NOT bandlimited
os.lf_trianglepos(f) // low-frequency triangle [0, 1)
For LFOs, always use os.lf_sawpos or a manual phasor — os.phasor is for audio-rate signals and has no advantage at LFO rates.
ALWAYS pipe sliders through si.smoo unless the parameter controls something that must be instantaneous (like a bypass toggle). Zipper noise from unsmoothed parameters is unprofessional.
Groups (for GUI organization)
// Horizontal group
freq = hslider("h:EQ/Frequency", ...);
// Vertical group
gain = hslider("v:EQ/Gain", ...);
// Tab group
freq = hslider("t:EQ/Frequency", ...);
// Nested groups
freq = hslider("h:EQ/v:Band 1/Frequency", ...);
Buttons and Checkboxes
bypass = checkbox("Bypass"); // 0.0 or 1.0
trigger = button("Trigger"); // 1.0 while held, 0.0 otherwise
Metadata annotations
// Style hints (host-dependent)
x = hslider("Name [style:knob]", ...); // prefer knob rendering
x = hslider("Name [style:led]", ...); // LED meter style
x = hslider("Name [style:numerical]", ...); // numeric entry
// Units (displayed in GUI)
x = hslider("Name [unit:Hz]", ...);
x = hslider("Name [unit:dB]", ...);
x = hslider("Name [unit:ms]", ...);
// Ordering (prefix number sorts in GUI)
x = hslider("[1] Rate", ...);
y = hslider("[2] Depth", ...);
Building Blocks: Correct Faust Idioms
Manual Phasor (best LFO base)
// φ[n] = (φ[n-1] + f/fs) mod 1
phasor(freq) = freq / float(ma.SR) : (+ : ma.decimal) ~ _;
// Use it:
lfo = phasor(0.5) : *(2.0 * ma.PI) : sin; // sine LFO at 0.5 Hz
// Essential for any feedback path — prevents DC accumulation
dcblock = _ <: _, (: fi.pole(0.9999)) :> -;
// Or use the library version:
dc = fi.dcblockerat(35.0); // -3dB at 35Hz
File Structure Template
declare name "EffectName";
declare author "Author / Organization";
declare description "One-line description · key features";
declare version "1.0";
declare license "GPL-3.0";
// ┌──────────────────────────────────────────────────────────────────────────┐
// │ EffectName — Full Name │
// │ Author │
// │ │
// │ Architecture: │
// │ · Key signal flow element 1 │
// │ · Key signal flow element 2 │
// └──────────────────────────────────────────────────────────────────────────┘
import("stdfaust.lib");
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ UI PARAMETERS ║
// ╚══════════════════════════════════════════════════════════════════════════╝
param1 = hslider("v:Effect/[1] Param1 [style:knob]", default, min, max, step) : si.smoo;
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ COMPONENT NAME ║
// ║ ║
// ║ Mathematical description of what this component does ║
// ║ Transfer function, difference equation, or invariant ║
// ╚══════════════════════════════════════════════════════════════════════════╝
component = ...;
// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ PROCESS ║
// ╚══════════════════════════════════════════════════════════════════════════╝
process = ...;
DeMoD Effect Design Standards
When producing effects under the DeMoD Audio Systems brand:
Comment Block Style
Use box-drawing characters (╔ ═ ╗ ║ ╚ ╝) for section headers. Include the mathematical derivation of non-trivial components in comments. Comments serve as both documentation and as proof of correctness.
Required Components for Any Modulated Effect
OU drift on all LFO instances — never bare os.osc or os.lf_sawpos for anything meant to sound organic
Padé saturator on all feedback paths — never raw fi.pole into feedback at high gains
Bandwidth-limiting LPF (fc ≈ 4–8 kHz) in feedback — models real analog circuit behavior