Skip to content

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 node

Every 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 node

cb 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 node

Event 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 node

cb 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 node

Code 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 node

cb 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.