[linux-audio-dev] rough rough ladspa docs

New Message Reply About this list Date view Thread view Subject view Author view Other groups

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.


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Mon May 08 2000 - 12:26:25 EEST