Anode == "audio node" Anodes are responsible for synthesizing or processing audio signals. Each Anode instance represents either an instance of a CLAP plugin or a built-in Modulator or Audio node. Anodes can respond several categories of methods. The categories that are central to most user-programs are the Note and Parameter families detailed below.
After creation, Anodes must be organized into an Agraph to define your audio scene. Usually you'll create and connect Anodes via the higher level Ascene methods.
let scene = await Ascene.BeginThread(this); // ensure audio engine is ready
// create two Anodes
let n1 = scene.NewAnode("Vital");
let n2 = scene.NewAnode("Hz.Mix");
// find the system output Anode
let out = scene.GetDAC();
// establish our audio connections
scene.Chain(n1, n2, out);
await ascene.Sync(); // wait for Anode and Agraph updates
n2.SetParam("gain", -2); // set Hz.Mix parameter (dB)
n2.NoteOn(35, .8); // play MIDI note 35, with velocity .8
await scene.Wait(scene.Seconds(.25)); // hold the note for 1/4 second
n2.NoteOff(35, 0); // release the note
Function | Description |
---|---|
Anode.Names() |
returns the names of all registered Anode classes |
Anode.Ids() |
returns the unique identifiers of all registered Anode classes |
You can programatically query the capabilities of a plugin with these functions. After working with a plugin you quickly learn its capabilities and you may be able to configure them during Anode instantiate and seen here.
Function | Description |
---|---|
Anode.DumpParams(nameOrId) |
logs the list of parameters of the requested Anode |
Anode.GetParamsFor(nameOrId) |
returns the list of parameters of the requested Anode |
Anode.GetFileRef(nameOrId) |
returns [pluginfilepath, pluginindex] |
Anode.GetAudioConfigs(nameOrId) * |
returns optional list of audio configurations. |
Anode.GetAudioInputs(nameOrId) |
returns array of default {name, nch} |
Anode.GetAudioOutputs(nameOrId) |
returns array of default {name, nch} |
Anode.GetInputNotePorts(nameOrId) |
returns object describing default input note ports or null |
Anode.GetOutputNotePorts(nameOrId) |
returns object describing default output note ports or null |
Anode.GetPreferredInputNoteDialect(nameOrId) |
returns one of "clap", "midi", "mpe", "midi2", null |
*
example output for Hz.Mix
[
{"id":0,"name":"mono","nin":2,"nout":1,"hasMainIn":true,"mainInNch":1,"mainInType":"mono","hasMainOut":true,"mainOutNch":1,"mainOutType":"mono"},
{"id":1,"name":"stereo","nin":2,"nout":1,"hasMainIn":true,"mainInNch":2,"mainInType":"stereo","hasMainOut":true,"mainOutNch":2,"mainOutType":"stereo"}
]
Method | Description |
---|---|
GetId() |
Returns the node's instance id (iid). |
Method | Description |
---|---|
Note(key, velocity, dur, when?, callerid?, noteId?) * |
Schedule a complete Note (On+Off) with its duration. |
NoteOn(key, velocity, when?, callerid?, noteId?) * |
Schedule a NoteOn event, NoteOff is expected to follow sometime later. |
NoteOff(key, velocity, when?, noteId?) |
Schedule a NoteOff event. Paired with a preceding NoteOn. |
NoteChoke(key, noteId?) |
Cancels all active notes on key and optional noteId. |
NoteExpression(expr, value, when?, noteId?, keyid?, chanid?) |
CLAP note expressions can be global or note-specific. |
NotePort(port) |
Updates the persistent port associated with this node. default: 0 |
NoteChannel(chan) |
Updates the persistent channel associated with this node. default: 0 |
MidiEvent(msg) |
Deliver the MIDI message to the node. msg is an array of MIDI bytes. |
async Wait(dur) |
convenience for scene.Wait, often called between noteOn and noteOff. Blocks. |
Note Parameter | Range | Description |
---|---|---|
key |
0-127 | MIDI key number, C4 is 60 |
velocity |
0-1 | Key Up or Down expression |
dur |
samples | The note duration measured in samples, covertible from Seconds by AScene |
when |
samples | The time to initiate the note in samples. When 0 we initiate the note asap and establish the current time as the origin for the coroutine's time context. Now non-zero values for when occur relative to that time origin. |
expr |
string or number | volume , pan , tuning , vibrato , expression , brightness , pressure |
*
returns [noteId, voiceid?]
useful for passing to NoteExpressions and Voices methods.
Anode parameters control the built-in synthesis or processing algorithm. CLAP parameter changes are either Set or Modulate. The resulting parameter value is the sum of the two. Parameter changes can be associated with an individual note or apply globally. Some Anodes (eg Vital, Surge XT) have more than 750 parameters. That's a lot of parameters.
Method | Description |
---|---|
Anode.DumpParams(nameOrId) |
class function to log the list of parameters of the requested Anode |
GetParamId(pid, module?) |
returns the parameter id of the parameter associated with nm, module? |
SetParam(pid, value, noteId?, when?) |
sets the parameter value globally or for a particular note and time. |
ModParam(pid, amount, noteId?, when?) |
modifies the parameter value globally or for a particular note and time. |
GetParamMenuLabel(pid, value) |
Returns the menu label for the enumerated parameter value. |
GetParamValueForMenuItem(pid, name) |
Returns the enumerated parameter value associated with menu label. |
You can control the setting of a CLAP Plugin instance in bulk through the use of Presets or by restoring a previously saved state. These operations may interupt an active plugin so usually you'll invoke these prior to song performance. Also, since these methods access your local disk, they are asynchronous (more here).
Method | Description |
---|---|
async LoadPreset(preset, load_key?) * |
Loads the named preset. |
async SaveState(filename) ** |
Saves the current state of an Anode to a file. |
async RestoreState(filename) |
Loads a previously saved state into an Anode. |
If your audio scene contains multiple anodes you would theoretically need
to save the state of each to preserve sufficient information to recreate
the scene. This is the way that most DAWs operate. In the context of
Hz
, you can recreate this behavior with your scripts but
it's more common to create state or presets incrementally on a per-node
basis and then load all states during your startup. In other words
there is no single scene-wide state file.
*
Presets differ by CLAP Plugin. Hz's built-in plugins accept a
parameter-value dictionary as a JSON string. FluidSynth
accepts
a pathname to a soundfont. Other plugins: YMMV.
**
Plugins may also offer save & restore options in their GUI so
you may find it easier to save states that way, then use RestoreState
at startup.
Here you can find some examples of this methods.
GUI refers to the optional user interface window or panel for the Anode. GUIs can either be window-base or webview. The latter is currently specific to Hz plugins and these guis appear in Hz tabbed-window-panels.
Method | Description |
---|---|
Show(subkey?) |
Causes the instance GUI (window or panel) to be displayed. If the optional subkey is a module name, its parameters will be shown. If subkey is "_sync", plugin will request full synchronization with host. |
Hide(subkey?) |
Hides the instance GUI. If the optional subkey is a module name, its parameters will be hidden. |