How Ecasound Manages LADSPA Plugin Memory
Ecasound manages memory for active LADSPA (Linux Audio Developer's Simple Plugin API) plugins by enforcing a strict separation between setup time and real-time processing. When integrating LADSPA plugins into an audio processing chain, Ecasound orchestrates memory management across two primary domains: the plugin's internal private state, which the plugin allocates itself during instantiation, and the external audio and control buffers, which Ecasound pre-allocates and assigns prior to playback. By handling all dynamic memory allocations during the graph configuration stage, Ecasound guarantees zero dynamic memory allocation or deallocation during the real-time processing loop.
Instantiation and Internal Memory
When a LADSPA effect is added to an Ecasound chain, Ecasound locates
the shared library object (.so) using the dynamic linker
(dlopen). Once the plugin descriptor is retrieved, Ecasound
initiates the memory lifecycle of the plugin instance:
- Calling
instantiate(): Ecasound calls the plugin descriptor'sinstantiate()function, passing the target sample rate. - Plugin Heap Allocation: The plugin itself allocates
whatever private instance data it requires (such as delay lines, filter
states, or operational variables) using standard system allocators
(
malloc,calloc, or C++new). - Handle Management: The plugin returns an opaque
LADSPA_Handlerepresenting that instance's memory space. Ecasound stores this pointer within its internal chain-operator wrapper objects.
Buffer Management and Port Connection
LADSPA plugins do not allocate memory for their input and output audio channels; the host is entirely responsible for audio data storage.
- Pre-allocation: During engine initialization and chain compilation, Ecasound pre-allocates fixed-size audio buffers (sized according to Ecasound's configured buffer size) and float variables for control ports.
- Port Binding: Ecasound calls the plugin’s
connect_port()function for every defined audio and control port. It passes memory addresses directly pointing to its internal audio buffers or control value addresses. - Shared Memory Usage: If multiple operators or chains interact, Ecasound passes the appropriate pointers through the signal path, avoiding unnecessary buffer copying whenever possible.
Real-Time Execution Safety
Once Ecasound switches into active audio processing mode:
- Zero Dynamic Allocation: Neither Ecasound nor the
LADSPA plugin is permitted to allocate or deallocate memory. Calling
memory functions like
malloc(),realloc(), orfree()can trigger locks, system calls, or page faults that lead to audio dropouts (xruns). - Buffer Processing: The processing thread repeatedly
invokes the plugin's
run()function, operating strictly within the memory addresses previously assigned duringconnect_port(). - State Activation: Prior to running, Ecasound calls
the plugin’s
activate()function (if defined), allowing the plugin to reset internal states (such as zeroing out delay buffers) without reallocating memory.
Instance Destruction and Deallocation
When an audio engine stops, a chain is modified, or Ecasound exits, the memory deallocation phase executes in reverse order of initialization:
- Deactivation: Ecasound invokes the plugin’s
deactivate()callback (if present), signaling that real-time processing has finished. - Instance Cleanup: Ecasound calls the plugin's
cleanup()function, passing the instance handle. The plugin executes its destructor logic, releasing all internal heap memory viafree()ordelete. - Host Buffer Release: Ecasound deallocates its own internal audio buffers, parameter trackers, and wrapper structures.
- Library Unloading: If no other active instances
depend on the loaded shared library, Ecasound closes the library handle
via
dlclose(), releasing the plugin's code segment from process memory.