How Ecasound Queries LADSPA Plugin Ports
Ecasound queries the input, output, and control ports of a LADSPA
(Linux Audio Developer's Simple Plugin API) plugin by dynamically
loading the plugin's shared library and inspecting the standardized
LADSPA_Descriptor structure. By parsing this descriptor,
Ecasound reads the total port count, evaluates bitmask descriptors to
classify whether each port is audio or control, determines data
direction (input or output), and retrieves port names and value ranges
to integrate the effect into its signal processing chain.
Shared Library Loading and Descriptor Access
Ecasound searches directories defined in the LADSPA_PATH
environment variable to locate plugin shared object files
(.so). When an effect is invoked, Ecasound uses the
standard POSIX dynamic linking interface (dlopen()) to load
the library into memory.
It then uses dlsym() to locate the mandatory entry-point
function:
const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);Ecasound calls ladspa_descriptor() starting at index
0 and increments the index until it encounters a
NULL return pointer or locates the specific plugin
requested by the user, matching either the plugin's unique integer ID or
its case-sensitive Label string.
Reading Port Count and Port Descriptors
Once a matching LADSPA_Descriptor is located, Ecasound
queries the plugin’s ports by reading the following structure
members:
PortCount: An unsigned long specifying the total number of ports (audio and control combined).PortDescriptors: An array ofLADSPA_PortDescriptorbitmasks with a length equal toPortCount.
Ecasound iterates through the array from index 0 to
PortCount - 1. For each index, it performs bitwise checks
against the flags defined in ladspa.h to classify the
port:
- Direction: It checks whether the port contains the
LADSPA_PORT_INPUTorLADSPA_PORT_OUTPUTflag. - Data Type: It checks whether the port contains the
LADSPA_PORT_AUDIOorLADSPA_PORT_CONTROLflag.
By combining these flags, Ecasound classifies each port into one of four functional categories:
- Audio Input: Receives incoming audio stream buffers.
- Audio Output: Emits processed audio stream buffers.
- Control Input: Accepts parameter values, automation, or user-defined control data.
- Control Output: Exposes monitoring data or feedback values generated by the plugin.
Querying Metadata and Parameter Hints
To present readable feedback to users and validate parameter limits, Ecasound evaluates two additional arrays in the descriptor:
PortNames: An array of strings providing human-readable labels for each port index. Ecasound displays these names in its command-line interface and preset descriptions.PortRangeHints: An array ofLADSPA_PortRangeHintstructures containing validation rules for control ports. Ecasound reads theHintDescriptorfield to determine whether a parameter has defined bounds (LADSPA_HINT_BOUNDED_BELOW,LADSPA_HINT_BOUNDED_ABOVE), whether it uses a logarithmic scale (LADSPA_HINT_LOGARITHMIC), whether it behaves as a toggle/boolean (LADSPA_HINT_TOGGLED), and which default value to apply if none is specified by the user.
Port Binding and Processing
After categorizing each port, Ecasound prepares the plugin for execution:
- It allocates float buffers for audio input and output streams.
- It assigns float storage for control inputs based on CLI arguments, controllers, or defaults.
- It calls the plugin's
connect_port()function for each port index, passing a pointer to the corresponding memory location:
descriptor->connect_port(InstanceHandle, PortIndex, &DataLocation);Whenever Ecasound processes an audio block, audio buffers and control values are read and written directly through these mapped memory addresses.