Every Phausto patch, from a bare sine wave to a forty-voice physical model, follows the same five-step lifecycle. Learn it once here and every later page is a variation on it.

1. The shortest program

A SineOsc with no arguments oscillates at 440 Hz — concert A. Open a Playground and evaluate these lines one at a time, with Cmd-D (macOS) or Ctrl-D, so you can hear each step take effect:

step by step Hello Phausto
"Create a sine oscillator — 440 Hz by default"
sine := SineOsc new.

"Wrap it in a DSP: the object that can actually make sound"
dsp := sine asDsp.

"Compile the FAUST code to native audio and allocate buffers"
dsp init.

"Start the audio thread — the tone begins here"
dsp start.

"Silence"
dsp stop.

Note what is not here: no sample rate, no buffer size, no output device, no build step, no file. A UGen becomes a DSP, and a DSP makes sound.

A UGen is not a sound SineOsc new makes no noise on its own. It is a description of a signal. Only asDsp hands that description to the FAUST engine, and only start connects the result to your speakers.

2. The DSP lifecycle

The same five messages govern every patch in this manual. Learning where each one belongs is most of what "knowing Phausto" means at the start.

Create — build a UGen or a chain of them, then send asDsp.
Initdsp init compiles the patch to machine code and allocates buffers.
Startdsp start hands the DSP to the audio thread. Sound begins.
Stopdsp stop halts output. The DSP stays alive and can be started again.
Destroydsp destroy frees the native resources for good.

2.1 The five messages

MessageEffect
asDspWrap the UGen chain in a DSP object
asDspWithName:Same, with a name you choose — useful when several DSPs run at once
initCompile and allocate. Required before start
startBegin audio output on the audio thread
stopHalt output; the DSP remains initialised
destroyRelease native memory and unregister the DSP
playConvenience: init and start together
playFor:Start, wait for a duration, then stop

stop and start can be alternated freely — that is the basis of live performance. init only needs to happen once.

2.2 Why destroy matters

A DSP holds memory allocated outside the Pharo heap, in the FAUST engine. Stopping a DSP does not release it. If you are working iteratively — evaluating a patch, changing it, evaluating again — destroy the old DSP before building the next one, or you will accumulate live DSPs that continue to consume CPU:

dsp stop.
dsp destroy.
Habit worth forming End every experiment with stop then destroy. Several lessons in MasterLu finish exactly this way, and for this reason.

3. Mono and stereo

asDsp on its own produces a mono DSP. Send stereo to the UGen first to duplicate the signal across two channels:

"A sawtooth, this time in stereo"
saw := SawOsc new.

"note 'stereo' before 'asDsp'"
dsp := saw stereo asDsp.

dsp init.
dsp start.
dsp stop.

The counterpart mono collapses a stereo signal back down to one channel. Both are ordinary messages on the UGen, so they compose with everything else — you will usually see stereo as the last thing before asDsp.

Reach for stereo by default Reverbs and other stereo effects — GreyHole, FreeverbMono's stereo siblings, ZitaRevStereo — expect two channels of input. Building in stereo from the start saves rewiring later. See Effects, Reverbs & Dynamics.

4. Opening the interface

FAUST derives a user interface from the sliders, buttons and numeric entries declared inside each module, and Phausto can render it as a Pharo window. One message:

dsp displayUI.

This is the fastest way to understand an unfamiliar UGen. Rather than reading its class comment, start it and look at what knobs appear. For UGens that need to be triggered — envelopes, drums, plucked strings — the UI is also the only way to make a sound before you have learned programmatic triggering.

You can also open a single control in its own window, which is convenient when you want one slider to hand during a performance:

slider := dsp sliderFor: 'SineOscFreq'.
slider openInWindow.

button := dsp buttonFor: 'DjembeTrigger'.
button openInWindow.

5. Finding and changing parameters

Every controllable value in a running DSP has a string name. Those names are generated from the UGen's label and the parameter's own label, so a PulseOsc contributes PulseOscFreq, PulseOscDuty and so on.

5.1 Discovering names with traceAllParams

You rarely need to guess. After init, ask the DSP to print everything it exposes to the Transcript:

dsp traceAllParams.
Why this matters more than it looks Most Phausto setters are supplied by shared traits rather than defined on the UGen class itself — SineOsc defines only initialize. Browsing a single class will therefore not show you its API, but traceAllParams always will.

5.2 Setting a value while it plays

PulseOsc is a square wave with a variable duty cycle — a good UGen to hear parameter changes on, because both of its controls have an obvious audible effect:

pulse := PulseOsc new.
dsp := pulse asDsp.
dsp init.
dsp start.

"Narrow the pulse — the timbre thins and gains harmonics"
dsp setValue: 0.2 parameter: 'PulseOscDuty'.

"Drop the pitch two octaves and a bit"
dsp setValue: 120 parameter: 'PulseOscFreq'.

"List everything this DSP exposes"
dsp traceAllParams.

dsp stop.
method setValue: aNumber parameter: aString

aNumber is the new value, in the parameter's own units — hertz, seconds, decibels or a normalised 0–1 range depending on the control. aString must match the parameter name exactly.

Only UI parameters are live A value baked in at construction time — SineOsc new freq: 200 — becomes a constant in the compiled DSP and cannot be changed afterwards. To change something at runtime, leave it at its default or give it a UI primitive. This trips up almost everyone once.

6. Something with a body

Oscillators are the "hello world" of synthesis, but Phausto's physical models are where the FAUST standard library earns its reputation. Djembe models the West African goblet drum:

perc := Djembe new.
dsp  := perc asDsp.
dsp init.
dsp start.

"Open the UI and press DjembeTrigger to strike the drum"
dsp displayUI.

dsp stop.

Then substitute Marimba for Djembe and run it again. The code is identical; only the model changes. That interchangeability — every UGen accepting the same lifecycle — is the point of the design. See Physical Modelling for the full family.

7. Where to go next

DocumentWhat it covers
Unit GeneratorsWhat every UGen has in common, and the families they fall into.
Connecting UGensThe operators that join UGens into chains, stacks and feedback loops.
Parameters & ControlNaming, triggering, sweeping and automating parameters.
Learn in the ImageThe same ground covered as sixteen runnable in-image lessons.

8. Troubleshooting

I evaluated the whole snippet at once and nothing happened

Evaluate line by line. Evaluating the block in one go runs start and stop within microseconds of each other, so the tone exists for no audible time.

dsp start complains that the DSP is not initialised

init has to happen first, and only once per DSP. If you rebuilt the UGen chain you also built a new DSP, and the new one needs its own init — see §2.1.

Sound keeps playing after I stopped it

You are probably hearing an earlier DSP that was never stopped. Each asDsp creates a new object; the variable dsp pointing somewhere else does not silence the old one. Keep the habit in §2.2.

setValue:parameter: does nothing

Either the name is wrong — run traceAllParams and copy it exactly, including capitalisation — or the value was fixed at construction time and is now a compiled constant. See §5.2.

A physical model or envelope makes no sound at all

It is waiting to be triggered. Open dsp displayUI and press the trigger button, or trigger it from code with dsp trig: 'DjembeTrigger'. See Parameters & Control.

The image gets slower every time I evaluate my patch

Undestroyed DSPs are stacking up. Send destroy before rebuilding — §2.2.