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:

  1. Calling instantiate(): Ecasound calls the plugin descriptor's instantiate() function, passing the target sample rate.
  2. 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).
  3. Handle Management: The plugin returns an opaque LADSPA_Handle representing 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.

Real-Time Execution Safety

Once Ecasound switches into active audio processing mode:

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:

  1. Deactivation: Ecasound invokes the plugin’s deactivate() callback (if present), signaling that real-time processing has finished.
  2. Instance Cleanup: Ecasound calls the plugin's cleanup() function, passing the instance handle. The plugin executes its destructor logic, releasing all internal heap memory via free() or delete.
  3. Host Buffer Release: Ecasound deallocates its own internal audio buffers, parameter trackers, and wrapper structures.
  4. 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.