Faust DSP: the second abstraction
FaustWave gives you two ways to build sound, and both end in the same place:
a DSP — a compiled Faust worklet, running. The Builder is the visual
route — nodes and cables, no code in sight. A Faust DSP (.dsp) is the
same engine with the covers off: you write Faust
source in a Monaco editor, hit Run, and the IDE compiles it to WebAssembly
and runs it as an AudioWorklet — exactly as a Builder does, because under the
hood a Builder generates Faust source too.
The word matters here, so it is worth being exact: "DSP" is what runs,
and builder and faust-dsp are the two documents that produce one. The
action families follow that split — builder.* edits a graph, dsp.* drives
whatever is running, either kind.
When to reach for a .dsp instead of the Builder:
- The stock nodes can't express it. Pitch envelopes, wavetable switching, frame-rate steppers, custom feedback topologies — anything the node catalog doesn't cover is a few lines of Faust.
- You want the whole
stdfaust.libuniverse. Every oscillator, filter, envelope, reverb and physical model in the Faust standard library is oneimport("stdfaust.lib");away. - You think in code. A DSP is a plain text file — diffable,
versionable, forkable on the Hub as
kind: "dsp".
What you do NOT give up: the mixer strip, the Patchbay routing, MIDI,
modulation, the sequencer — a running .dsp is a first-class citizen
of the same audio graph.
Lifecycle in one paragraph
documents.add { type: "faust-dsp" } creates the module and its project
file immediately (auto-placed in the project's assets/, autosaved on
every edit). Run compiles + starts the worklet; Stop disposes it but keeps
the mixer strip. Editing while running does NOT hot-swap — Stop + Run to
hear changes. The file lives with your project and travels with a project
export.