[Clam-devel] Re: Exporting CLAM Processings as Ladspa plugins

David García Garzón dgarcia at iua.upf.edu
Wed Jul 9 11:16:26 PDT 2008

Well, the LADSPA-on-click feature is getting closer. :-)

I just integrated building Ladspas from a network using the same API i used 
for Processings. I put the whole thing in:

Exporter class was also moved out of the LaspaLibrary class so the user code 
now looks much like this:
--- MyClamLadspaPlugin.cxx
#include "AudioMultiplier.hxx"
#include "AudioAmplifier.hxx"
#include "Oscillator.hxx"
#include "LadspaNetworkExporter.hxx"
#include "LadspaProcessingExporter.hxx"
#include "LadspaLibrary.hxx"

static CLAM::LadspaLibrary library;

extern "C" const LADSPA_Descriptor * ladspa_descriptor(unsigned long index)
    static CLAM::LadspaProcessingExporter<CLAM::Oscillator> a1(library, 3000);
    static CLAM::LadspaProcessingExporter<CLAM::AudioMultiplier> a2(library, 
    static CLAM::LadspaProcessingExporter<CLAM::AudioAmplifier> a3(library, 
    static CLAM::LadspaNetworkExporter n1(library);
    return library.pluginAt(index);
--- end of MyClamLadspaPlugin.cxx

Notice that the LadspaNetworkExporter has no options at all to specify the 
network or the ladspa metadata (such id, name, label, maker, copyright...)
I didn't changed the existing implementation behaviour: the network used is 
specified by the CLAM_NETWORK_PLUGIN_PATH environment variable and the 
metadata, even the ladspa id, is hardcoded. Of course that this is not 
convenient as you are limited to a single network and it is going to change.

I foresee two use cases:
- Directory loading: Just like the plugins, there is a set of standard paths 
were to look for networks. This requires a way to specify metadata within the 
network. This could also be a default CLAM plugin installed with clam.

- Embeded data: Embed the network in C string literal or as binary data (ie. 
using qrc or objcopy[1]) and provide the string  as parameter with the 
required metadata. This is convenient to hide any clam dependencies to final 
plugin users.

The simplest option now is providing directly the network path with the 
metadata. It could work now for testing but i think it is not that usable by 

Any other idea?

[1] Yes, Pau, i found the command to embed files as executable data :-) And it 
is a default in gcc tool chain so it is also available in mingw!

On Monday 07 July 2008 21:49:01 David García Garzón wrote:
> I have been revisiting the mechanisms in clam to build a LadspaPlugin. I
> noticed that ProcessingClass2Ladspa sources were blacklisted and so were
> the examples. So 'fix or remove!' and this time i fixed. Such class is
> about converting Processings into plugins, and although our plan is doing
> such a thing with Networks, i considered cleaning up that interface a nice
> exercise.
> At the end you can define your plugin just by doing this:
> ----- MyLadspaPlugin.cxx
> #include "AudioMultiplier.hxx"
> #include "Oscillator.hxx"
> #include "ProcessingClass2Ladspa.hxx"
> static CLAM::LadspaLibrary library;
> extern "C" const LADSPA_Descriptor * ladspa_descriptor(unsigned long index)
> {
>     static CLAM::LadspaLibrary::ProcessingExporter
> 		<CLAM::Oscillator> a1(library, 3000);
>     static CLAM::LadspaLibrary::ProcessingExporter
> 		<CLAM::AudioMultiplier> a2(library, 3001);
>     return library.pluginAt(index);
> }
> This has several benefits from the blacklisted version:
> * You can define multiple plugins types in a single dll
> * You don't have the undefined 'Instance' linker error by including the
> functionality on the library so that the generic code can be back to clam
> core without blacklisting
> * Several CLAM based ladspa libraries loaded in a single host don't collide
> * The library mechanism is general, based on inserting LADSPA_Descriptor
> structures into the LadspaLibrary, so we could easily add an object that
> inserts descriptors for Networks, the initial goal.
> * Template code has been reduced nearly to NULL
> Some noticeable changes:
> * I added "CLAM_" and "CLAM " prefixes to the plugins name and labels.
> * Bug squashing (buffer allocation, reinstanciating, leaks...)
> Some work is still needed to clean up the internal implementation but the
> API shown above is pretty nice and ready to become stable (and moved back
> to core), so i wanted to ask you for API preferences.
> * Do you like ProcessingExporter being an inner class, or it would be
> better having a CLAM::LadspaProcessingExporter?
> * Names? We should avoid conceptual clash with classes to load ladspas as
> host.
> (The former class ProcessingClass2Ladspa has become a hidden implementation
> detail and very likely to be changed/splitted/renamed/removed on next
> refactorings)
> David.

More information about the clam-devel mailing list