Purge¶
The purge system controls which Kontakt sample groups are resident in RAM. Groups not needed are evicted; groups that are needed are kept loaded. This directly affects memory footprint and, for large instruments, whether certain notes are audible at all.
Why Purge Exists¶
A multi-layer, multi-sound instrument may have thousands of sample groups. Loading all of them at once wastes RAM and slows Kontakt startup. The purge system lets the product declare what it currently needs — based on which layers are enabled, which sounds are assigned, which mic positions are active — and IVLS applies the minimum necessary changes to bring actual group load state in line.
Key Concepts¶
The cb Purge Callback¶
Any node that knows which groups are required implements cb Purge. Inside it the node writes ON or OFF into purge.group_states[] for each relevant group index. After all Purge callbacks have run, IVLS applies the minimal set of Kontakt purge_group / allow_group calls to reconcile current state:
cb Purge:
for purge_layer := 0 to 3
purge.group_states[plc.layers.get_layer_sound_group(purge_layer)] :=
plc.layers[purge_layer].enable
end forA node does not need to know about groups it does not own. Multiple nodes each write their portion; writes are cumulative across all registered Purge nodes.
purge.default_group_state¶
Before any cb Purge callback runs, purge.group_states[] is filled with purge.default_group_state. The SDK initializes this to TRUE (ON), meaning all groups start loaded by default. Products that want conservative purging override this to OFF in their cb Init:
cb Init:
purge.default_group_state := OFFWith OFF (the common product-level override), any group not explicitly set to ON by a cb Purge callback will be evicted. This is conservative mode: opt specific groups in. The risk is forgetting a group. With the SDK default of ON (permissive), all groups remain loaded unless explicitly evicted — simpler but wastes RAM on groups that are never played.
purge.execute()¶
purge.execute() triggers a purge cycle. Call it explicitly after any state change that affects which groups are needed:
// In par_cb.response:
case plc.layers.par.ENABLE
call uir.update()
purge.execute()
case plc.layers.par.SOUND_ID
plc.group_update(layer)
purge.execute()Do not call purge.execute() on every knob turn. Only call it when the set of required groups may have changed.
Common Trigger Points¶
- A sound assignment changes (par
SOUND_ID) - A layer is enabled or disabled (par
ENABLE) - The browser opens or closes (keep preview group loaded)
- A console channel is enabled or disabled
Multiple Purge Nodes¶
A product can have multiple cb Purge implementations. They all run when purge.execute() is called. A later write for the same group index wins. This allows clean separation — one node handles layer groups, another handles console mic-position groups.
Console-Driven Purge¶
When the Console is present, toggling a channel must call purge.execute() from console.ui_cb.response:
function console.ui_cb.response(ch, slot, type)
select type
case console.ui.cb_type.CHANNEL_ENABLED
purge.execute()
end select
end functionWithout this, toggling a channel off does not evict its groups from RAM.
Connections to Other Parts of IVLS¶
Purge is called from engine-box par_cb.response callbacks, from console channel-toggle handling, and from browser load callbacks. The group index arithmetic that maps a sound_id to a Kontakt group index is product-specific and is the most common source of purge bugs.
Patterns and Caveats¶
The most common purge bug: get_sound_id_grp_idx(sound_id) (or the equivalent) returns the wrong index. Incorrect group offset arithmetic causes silent groups or groups that never purge. Verify the mapping explicitly during development.
The browser preview guard: Keep the preview group loaded while the browser is open, even when no key references it:
if phr.gui.is_browser_open()
purge.group_states[0] := ON
end ifWithout this, previewing a sound before it is assigned to a key will produce silence.
Debugging checklist when a group plays silently or not at all:
1. Check that purge.execute() is called after the assignment
2. Check that cb Purge maps the sound_id to the correct group index
3. Verify purge.default_group_state is set as expected (SDK default is ON; most products override to OFF in cb Init)
4. Confirm the group index arithmetic is correct
Related¶
- engine-box — par_cb.response is the primary caller of purge.execute()
- console — channel enable/disable must also trigger purge.execute()