Subject: [linux-audio-dev] rough rough ladspa docs
From: David Benson (daveb_AT_idealab.com)
Date: Mon May 08 2000 - 11:38:15 EEST
I've written rather rough LADSPA documentation
in sgml, using the linuxdoc stylesheet.
It's an experiment in some ways; I don't know much about sgml.
I really don't want to maintain the LADSPA docs
but I do want to make a few more revisions,
so for now send patches to me, but I also
would love to hand them off...
Help filling in the TODO sections is heavily requested...
(As is help on all fronts :)
Here are the urls:
http://www.ffem.org/gdam/ladspa-doc/ladspa.html
http://www.ffem.org/gdam/ladspa-doc/ladspa.txt
source sgml:
http://www.ffem.org/gdam/ladspa-doc/ladspa.sgml
tarball w/ silly makefile:
http://www.ffem.org/gdam/ladspa-doc/ladspa-0.0001.tar.gz
some of this is ripped straight from ladspa.h;
no attribution is made, sorry...
Here the ascii rendering...
============================================================
Warning: the nested lists are flattened in their conversion
from .sgml. This is confusing at times.
============================================================
LADSPA Plugin Developers' Documentation
various at linux-audio-dev_AT_ginette.musique.umontreal.ca
v0.000001, May 7, 2000
This document describes how to write hosts and plugins for the LADSPA
plugin format.
______________________________________________________________________
Table of Contents
1. Introduction
1.1 Terminology
1.2 How Sound is Processed
1.3 The Plugin Lifecycle
2. The LADSPA Plugin Format
2.1 Obtaining LADSPA_Descriptors
2.2 The descriptor's data Now we need to look at the LADSPA_Descriptor structure. It consists of a number of members which describe the function, and a collection of function pointers which provide its implementation.
2.3 The descriptor's implementation
3. Writing LADSPA Plugins
3.1 Initial Organization
3.2 Writing the plugin instance structure
3.3 Writing ladspa_descriptor
3.4 Writing the virtual functions.
3.4.1 Writing instantiate and activate
3.4.2 A trivial connect_port implementation
3.4.3 Notes on the run function.
3.4.4 Cleaning up
4. Writing LADSPA Hosts
4.1 General Considerations
4.2 Finding which plugins are available.
4.3 Loading and using a plugin
______________________________________________________________________
1. Introduction
LADSPA is the Linux Audio Developer's Simple Plugin Architecture.
1.1. Terminology
There are several common bits of terminology:
plugin
A shared library that can be loaded dynamically. That is,
plugins can be loaded and unloaded as the user requests.
plugin descriptor
a single sound-producing/consuming type. A plugin may contain
several plugin descriptors, each with an index within plugin.
The indices must be consecutive and start with 0.
host
The program which will load the plugins.
The standard describes the binary interface for a plugin to present
itself to the host.
There are several other features of the format:
ports
are the only way to pass data from the host to the plugin and
back.
input ports
are ports which communicate data from the host to the plugin.
output ports
are ports which communicate data from the plugin to the host
control ports
are input or output ports whose values are constant over each
block of audio rendered.
audio ports
are input or output ports for audio data. Audio data is in
floats, but you should use the LADSPA_Data typedef.
LADSPA_Descriptor
is a type which encapsulates a single plugin descriptor.
1.2. How Sound is Processed
In LADSPA, sound is processed in contiguous blocks, whose length is
controlled by the host (it is the second parameter, SampleCount, to
run).
When the host calls the plugin's run or run_adding functions it must
have connected buffers to every port. For audio ports, the buffers
must as long as SampleCount. Control ports always use just a single
sample of data.
Notice that the amount of sound input is always equal to the amount of
sound output.
1.3. The Plugin Lifecycle
o the plugin is loaded (using a system-specific method like dlopen or
g_module_open).
o the plugin descriptor is obtained using the plugin's
ladspa_descriptor function, which may allocate memory.
o the host uses the plugin's instantiate function to allocate a new
(or several new) sample-processing instances.
o the host must connect buffers to every one of the plugin
descriptor's ports. It must also call activate before running
samples through the plugin.
o the host processes sample data with the plugin by filling the input
buffers it connected, then calling either run or run_adding.
o the host deactivates the plugin handle. It may opt to activate and
reuse the handle, or it may destroy the handle.
o the handle is destroyed using the cleanup function.
o the plugin is closed. It's _fini function is responsible for
deallocating memory.
2. The LADSPA Plugin Format
2.1. Obtaining LADSPA_Descriptors
The ladspa format specifies how to obtain the LADSPA_Descriptors from
a given plugin. All LADSPA plugins must define a function
______________________________________________________________________
LADSPA_Descriptor* ladspa_descriptor(unsigned long Index);
______________________________________________________________________
which will return each LADSPA_Descriptor by index. It must return
NULL for all invalid indices. So a simple way to determine the number
of plugins for a given plugin is:
______________________________________________________________________
unsigned long num_plugins = 0;
while ((*ladspa_descriptor_func)(num_plugins) != NULL)
num_plugins++;
______________________________________________________________________
More commonly though, you'll need to use the LADSPA_Descriptor that
that function returns.
2.2. The descriptor's data Now we need to look at the LADSPA_Descrip-
tor structure. It consists of a number of members which describe the
function, and a collection of function pointers which provide its
implementation.
Here are the data members:
unsigned long UniqueID
This numeric identifier indicates the plugin type uniquely.
Plugin programmers may reserve ranges of IDs from a central body
to avoid clashes. Hosts may assume that IDs are below 0x1000000.
const char * Label
This identifier can be used as a unique, case-sensitive
identifier for the plugin type within the plugin file. Plugin
types should be identified by file and label rather than by
index or plugin name, which may be changed in new plugin
versions. Labels must not contain white-space characters.
LADSPA_Properties Properties
This indicates a number of properties of the plugin.
const char * Name
This member points to the NUL-terminated name of the plugin
(e.g. "Sine Oscillator").
const char * Maker
This member points to the null-terminated string indicating the
maker of the plugin. This can be an empty string but not NULL.
const char * Copyright
This member points to the null-terminated string indicating any
copyright applying to the plugin. If no Copyright applies the
string "None" should be used.
unsigned long PortCount
This indicates the number of ports (input AND output) present on
the plugin.
const LADSPA_PortDescriptor * PortDescriptors
This member indicates an array of port descriptors. Valid
indices vary from 0 to PortCount-1.
const char * const * PortNames
This member indicates an array of null-terminated strings
describing ports (e.g. "Frequency (Hz)"). Valid indices vary
from 0 to PortCount-1.
const LADSPA_PortRangeHint * PortRangeHints
This member indicates an array of range hints for each port (see
above). Valid indices vary from 0 to PortCount-1.
void* ImplementationData
This may be used by the plugin developer to pass any custom
implementation data into an instantiate call. It must not be
used or interpreted by the host. It is expected that most plugin
writers will not use this facility as LADSPA_Handle should be
used to hold instance data.
The PortDescriptors and PortRangeHints members describe the available
ports. The PortDescriptors are just bitmasks that are OR'd together:
LADSPA_PORT_INPUT
indicates that the port is an input.
LADSPA_PORT_OUTPUT
indicates that the port is an output.
LADSPA_PORT_CONTROL
indicates that the port is a control port.
LADSPA_PORT_AUDIO
indicates that the port is a audio port.
2.3. The descriptor's implementation
The LADSPA_Descriptor contains a number of function pointers which
implement the plugin. The primary function is run which renders and
processes samples, but you must also define functions to manage the
plugin's memory.
instantiate
function is the function which should allocate a new plugin
handle. TODO: elaborate.
activate
function is the function which clear or reset a plugin handle.
TODO: elaborate.
connect_port
function allows the host to specify input buffers to the plugin.
TODO: elaborate.
run
function processes samples. TODO: elaborate.
run_adding
function is optional. It is the same as run except it adds the
output to the output buffer instead of overwriting it. If you
don't want to implement this, leave the function pointer NULL.
I (daveb) don't recommend implementing or using this function as
it is not usually much of a savings.
deactivate
function should free the memory allocated by activate. TODO:
elaborate.
cleanup
function should free a plugin instance. TODO: elaborate.
3. Writing LADSPA Plugins
3.1. Initial Organization
The first thing you must do is figure out the specifics of how you
want your plugins to be organized.
o Do you want several plugin descriptors in the same plugin for
implementation convenience?
o How many audio inputs and audio outputs should each descriptor
have? How many control ports?
3.2. Writing the plugin instance structure
It is usually easiest to write a struct corresponding to the handle of
a plugin descriptor.
The structure may however you want; however, it is necessary to store
somewhere the various buffer pointers the host has connected to us
(via connect_port).
So here is a typically example, from the ladspa.tgz package, filter.c:
______________________________________________________________________
typedef struct {
LADSPA_Data m_fSampleRate;
/* filter-specific data deleted. */
/* Ports:
------ */
LADSPA_Data * m_pfCutoff;
LADSPA_Data * m_pfInput;
LADSPA_Data * m_pfOutput;
} SimpleFilter;
______________________________________________________________________
3.3. Writing ladspa_descriptor
Once you have decided this, you must write the ladspa_descriptor
function. It takes an integer for the plugin index, and returns the
LADSPA_Descriptor. It's exact implementation is up to the plugin, but
here is a fairly generic code outline:
______________________________________________________________________
static LADSPA_Descriptor* the_descriptor = NULL;
LADSPA_Descriptor* ladspa_descriptor(unsigned long index)
{
if (index != 0)
return NULL;
if (the_descriptor != NULL)
return the_descriptor;
the_descriptor = (LADSPA_Descriptor*) calloc(sizeof(LADSPA_Descriptor), 1);
if (the_descriptor == NULL)
return NULL;
... You must fill in the various fields of the_descriptor ...
return the_descriptor;
}
void _fini()
{
if (the_descriptor != NULL)
{
free(the_descriptor);
the_descriptor = NULL;
}
}
______________________________________________________________________
3.4. Writing the virtual functions.
The data fields are fairly easy to fill. We describe the function
pointers in more detail.
3.4.1. Writing instantiate and activate
These are the functions which allocate and clear the plugin.
instantiate
This must call malloc to allocate space for a plugin instance.
activate
This should clear the state of the plugin. For example, it is
important that calling deactivate, then activate should clear
all the buffers.
3.4.2. A trivial connect_port implementation
Here is the simple filter connect_port implemenation:
______________________________________________________________________
void
connectPortToSimpleFilter(LADSPA_Handle Instance,
unsigned long Port,
LADSPA_Data * DataLocation) {
SimpleFilter * psFilter;
psFilter = (SimpleFilter *)Instance;
switch (Port) {
case SF_CUTOFF:
psFilter->m_pfCutoff = DataLocation;
break;
case SF_INPUT:
psFilter->m_pfInput = DataLocation;
break;
case SF_OUTPUT:
psFilter->m_pfOutput = DataLocation;
break;
}
}
______________________________________________________________________
3.4.3. Notes on the run function.
the run function must be able to process the number of samples the
host asks for.
TODO: elaborate.
TODO: describe run_adding.
3.4.4. Cleaning up
You may wish to implement the deactivate function to undo any memory
allocation done in activate but it is often unnecessary, and is
usually left NULL.
But you must implement cleanup to deallocate the plugin handle and the
buffers it uses.
4. Writing LADSPA Hosts
This section contains a number of considerations, and some advice, for
LADSPA hosts.
Of course, LADSPA hosts vary a lot more than the plugins, so we cannot
specify a cookbook recipe.
4.1. General Considerations
Before trying to host LADSPA plugins, figure you what the limits of
your hosts support should be. Hopefully these guidelines will be of
some value:
o Hosts should be able to inspect any plugin and determine its
suitability. For example, for many applications an output port is
mandatory, but the format doesn't mandate that. Be clear in your
error handling.
o Hosts should generally provide an interface to the control ports.
o Hosts may wish to cope with multi-channel sound. Some LADSPA
plugins directly deal with stereo as two separate ports; others
will require that you instantiate two handles.
4.2. Finding which plugins are available.
Hosts should obey the LADSPA_PATH environment variable, and may
actively seek out plugins there.
4.3. Loading and using a plugin
Here is how the host should use a plugin:
o It should obtain the LADSPA_Descriptor* from the ladspa_descriptor
function.
o Create and destroy plugin instances:
o call instantiate to make each instance you want.
o call activate to prepare/clear the instance for use.
o call connect_port for each port.
o call run or run_adding as many times as you want.
o call deactivate if it is not NULL.
o call cleanup on the plugin handle (returned from instantiate).
o Unload the plugin when you are down with all plugin instances that
reference it.
This archive was generated by hypermail 2b28 : Mon May 08 2000 - 12:26:25 EEST