What you can change while the sound is running, how it gets a name, and every way to change it — by hand, from code, or on a schedule.

1. Three kinds of argument

Almost every Phausto setter is declared as taking aNumberOrABoxOrASymbol, and that signature is the single most important thing on this page. The kind of argument you pass decides whether the value is frozen, modulated, or exposed as a control.

1.1 A number is a constant

osc := SineOsc new freq: 440.

440 is compiled into the DSP as a literal. It is efficient and it is permanent: no parameter appears in the UI, and setValue:parameter: has nothing to address. Use numbers for values that genuinely never change.

1.2 A UGen is modulation

"Vibrato: ±20 Hz at 6 Hz around a 440 Hz centre"
osc := SineOsc new freq: (LFOTri new freq: 6) * 20 asBox + 440 asBox.

The value now comes from another part of the signal graph and changes every sample. This is how envelopes, LFOs and audio-rate modulation are wired — see Envelopes & Modulation.

1.3 A symbol is a control

osc := SineOsc new freq: #myFreq.

Passing a symbol creates a named, runtime-controllable parameter. It appears in displayUI, it shows up in traceAllParams, and setValue:parameter: can reach it. This is the mechanism you need for anything you intend to perform with.

The single most common mistake Building a patch with numbers everywhere and then discovering nothing can be changed while it plays. If you want to control it later, give it a symbol or a UI primitive now.

Symbols also convert directly into widgets when you want to specify a range:

ExpressionResult
#gate asPhButtonA momentary button named gate
#cutoff asPhHSliderA horizontal slider named cutoff
'Level' asPhFaderA fader from a string label
#freq <- 440Set a symbol-named parameter's value

2. How parameters get their names

A parameter's name is its UGen's label followed by the parameter's own label. A PulseOsc whose label is the default class name therefore contributes PulseOscFreq and PulseOscDuty.

Relabel the UGen and every one of its parameters is renamed with it:

"Two oscillators that would otherwise share parameter names"
left  := SineOsc new label: 'Left'.
right := SineOsc new label: 'Right'.

"now LeftFreq and RightFreq, individually addressable"
dsp setValue: 440 parameter: 'LeftFreq'.
dsp setValue: 443 parameter: 'RightFreq'.

The same technique makes an arbitrary instrument work with playNote:prefix:dur:, which looks for a frequency and a gate under a prefix you choose:

synth := ElecGuitar new
  freq:    #ElecGuitarFreq;
  trigger: #ElecGuitarTrigger.
Label early Labels are baked in when the DSP is compiled. Renaming after asDsp has no effect on the running DSP — rebuild it.

3. Discovering what exists

You should almost never guess a parameter name. After init, the DSP can list everything it exposes:

MessageReturns
traceAllParamsPrints every parameter and its current value to the Transcript
allParametersThe parameters as objects
getParamCountHow many there are
getParamAddress:The name at a given index
getParamIndex:The index of a given name
getParamValue:The current value of a named parameter
includesParameter:Whether a name exists — useful before setting it
getUIButtonsJust the buttons
getUIKnobsJust the continuous controls
getUIItemsEvery UI item
getJSONThe full FAUST UI description as JSON
dsp traceAllParams.
dsp getParamValue: 'PulseOscDuty'.
(dsp includesParameter: 'PulseOscFreq') ifTrue: [ "safe to set" ].
Why this matters here more than elsewhere Phausto's setters mostly come from shared traits, so browsing a UGen class does not reveal its API. traceAllParams is the authoritative answer and costs one line.

4. Setting values

method setValue: aNumber parameter: aString
dsp setValue: 0.2 parameter: 'PulseOscDuty'.
dsp setValue: 120 parameter: 'PulseOscFreq'.

Values are in the parameter's own units — hertz, seconds, decibels, or a normalised 0–1 range, depending on the control. Out-of-range values are clamped to the declared minimum and maximum rather than raising.

The index form, setValue:parameterIndex:, avoids the name lookup and is marginally faster; it is worth using inside a tight control loop, but the name form is clearer everywhere else.

Silence is the failure mode Setting a name that does not exist does nothing and reports nothing. If a change appears to have no effect, check the spelling and capitalisation against traceAllParams before assuming the value is wrong.

5. Triggering

Envelopes, drums and plucked models do nothing until gated. A button parameter is a signal that is 1 while pressed and 0 otherwise, and trig: presses it from code.

MessageEffect
trig: aStringFire the named trigger
trig: aString for: secondsHold the gate open for a duration, then release
playNote: n prefix: aString dur: secondsSet the frequency from a MIDI note number and gate it for a duration
syncTrigResetReset synchronised triggers to a common origin
"Strike a drum"
dsp trig: 'DjembeTrigger'.

"Hold a note for a quarter of a second"
dsp trig: 'ADSREnvGate' for: 0.25.

"Play middle C for a quarter of a second"
dsp playNote: 60 prefix: 'ElecGuitar' dur: 0.25.

The difference between trig: and trig:for: matters for sustaining instruments. A percussion model only needs an instant; an ADSR held open by trig: alone will sit in its sustain stage indefinitely.

6. Sweeps and ramps

A parameter can be moved gradually rather than jumped, which is the difference between a filter that clicks and one that sweeps:

method sweepToValue: aTarget parameter: aString in: seconds
"Open the filter over two seconds"
dsp sweepToValue: 8000 parameter: 'MoogVcfFreq' in: 2.

sweepToMfValue:parameter:in: is the variant for parameters expressed as multiplication factors rather than absolute values.

Or smooth it in the graph For a control that will be moved often, put the smoothing in the DSP instead: append smoo to the widget, or use one of the PhSmoo family. That way every change is smoothed, including ones made by hand in the UI. See Envelopes & Modulation.

7. Setting many at once

Phausto extends Array so a collection of values can be applied to a DSP in one message — convenient when recalling a preset or stepping a sequence:

MessageEffect
anArray setValue: aFloat parameter: aString forDsp: aDspApply a value across a DSP from an array context
anArray trig: aString for: seconds forDsp: aDspFire a trigger for a duration from an array context

For structured state — saving, recalling and interpolating whole parameter sets — Phausto has DSPParameter and DSPParameterStore, described in DSP & Parameter API.

8. Individual widgets

displayUI opens everything at once. When you want one control on screen — during a performance, or to keep a specific knob to hand — open it alone:

MessageEffect
displayUIThe whole generated interface
sliderFor:A slider presenter for one named parameter
buttonFor:A button presenter for one named trigger
openSliderFor:Build and open a slider in one step
openButtonFor:Build and open a button in one step
keyBoardFor:A piano keyboard bound to a named instrument
s1 := dsp sliderFor: 'tempo'.  s1 openInWindow.
s2 := dsp sliderFor: 'freq'.   s2 openInWindow.

Nested FAUST groups produce path-like names, so a parameter inside a demo module may be addressed as something like 'Freeverb/0x00/RoomSize'. Copy the exact string from traceAllParams.

9. Where to go next

DocumentWhat it covers
UI PrimitivesSliders, buttons and entries in full, with their metadata.
Setter TraitsEvery setter selector and which family provides it.
DSP & Parameter APIThe complete DSP protocol and the parameter store.
Sequencing & SamplingDriving all of this from patterns.

10. Troubleshooting

setValue:parameter: silently does nothing

Either the name is wrong, or the value was fixed as a number at construction time and is now a compiled constant. Check with traceAllParams — §3 — and see §1.1.

The parameter I want is not in traceAllParams at all

It was never exposed. Rebuild the UGen passing a symbol or a UI primitive instead of a number — §1.3.

Two UGens respond to the same parameter name

They share a label. Give one its own label: — §2.

Changing a value produces an audible click or zipper noise

The jump is instantaneous. Sweep it, or smooth it inside the graph — §6.

My envelope triggers but never releases

trig: opens the gate and leaves it open. Use trig:for: with a duration, or playNote:prefix:dur: — §5.

A parameter name has slashes and hex digits in it

That is a nested FAUST group path, normal for demo modules and complex instruments. Copy it verbatim — §8.