Callbacks¶
We've seen that nodes contain callbacks -- snippets of code that run in response to events. But which callbacks are available, and when does each one fire? This page introduces the callbacks you'll use most often as a beginner.
Initialization Callbacks¶
cb Init¶
cb Init runs once when the instrument first loads. This is where you declare variables, create data structures, and do any one-time setup that your node needs.
node MyFeature:
cb Init:
declare my_value := 0
declare my_name := "Hello"
end nodeEvery node in your product has its cb Init executed in the order the nodes appear in IVLS_NODES.
cb FirstLoad¶
cb FirstLoad also runs once on the very first load of the instrument. The difference from Init is when it runs: FirstLoad fires during the first preset load, after Init has already completed.
This is the callback where you set up flows (the pipelines that power the playback system). You'll see this in detail in Unit 2 - Playback System.
node MyFeature:
cb FirstLoad:
{ Set up flows and other one-time configuration }
end nodecb Reload¶
cb Reload runs every time a preset or snapshot is loaded. This includes the initial load and every subsequent preset change. You may encounter the older name cb PCCB in existing code -- both are dispatched by the framework, but new code should use cb Reload.
This is where you synchronize your node's state with whatever values were restored from the preset. If you have UI elements that need updating, or internal state that depends on saved parameters, Reload is where you handle that.
node MyFeature:
cb Reload:
{ Synchronize state after a preset loads }
end nodeEvent Callbacks¶
cb CC¶
cb CC fires whenever a MIDI CC (Continuous Controller) message is received. Inside this callback, you can check CC_NUM to see which controller changed, and CC[CC_NUM] to read its value.
node MyFilter:
cb CC:
if CC_NUM = 1 { Mod wheel }
my_filter_value := CC[1]
end if
end nodecb TransportStart / cb TransportStop¶
cb TransportStart and cb TransportStop fire when the host DAW starts or stops playback. These are useful for resetting counters, syncing to the transport, or cleaning up state.
node MySequencer:
cb TransportStart:
step_position := 0
cb TransportStop:
{ Clean up any active state }
end nodeCode Structure Callbacks¶
cb Functions¶
cb Functions is where you define helper functions and on ui_control() handlers. It doesn't "fire" in response to an event -- instead, it's a place where the compiler expects to find function definitions that your other callbacks can call.
node MyFeature:
cb Functions:
function my_helper(value) -> result
result := value * 2
end function
cb CC:
if CC_NUM = 1
my_value := my_helper(CC[1])
end if
end nodecb UICBS¶
cb UICBS fires when a UI widget changes -- a knob is turned, a button is clicked, a menu selection changes. This is the callback where you respond to user interaction with your instrument's interface. The details of UI programming will be covered in Unit 4 - GUI.
Playback Callbacks¶
cb NoteOn / cb NoteOff¶
cb NoteOn and cb NoteOff are the callbacks that handle note playback. However, unlike the callbacks above, they don't simply fire whenever a MIDI note arrives. They are special -- they participate in the IVLS playback system and only execute when a voice reaches the node through a flow.
We'll cover these properly in Unit 2 - Playback System. For now, just know they exist, and that setting them up requires a bit more infrastructure than the other callbacks.
These are the callbacks you'll encounter most often in the early stages of building an instrument. IVLS has additional callbacks for more specialized purposes (timers, async operations, PGS communication), but the ones listed here cover the vast majority of what a typical instrument needs.