[linux-audio-dev] LADSPA Non-Sequential API (was non-causal)

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

Subject: [linux-audio-dev] LADSPA Non-Sequential API (was non-causal)
From: Richard W.E. Furse (richard_AT_muse.demon.co.uk)
Date: Sat Dec 09 2000 - 01:16:31 EET


Sorry for the delay - I've not even changed things much!

At the end of this email is a new form of the LADSPA API with
non-sequential (non-causal) access included. This is a proposed development
form and not an official version, so please feel free to suggest changes!
I've had a go at making the non-sequential API a little more intelligible,
but it's still not great. Separate tutorial documents for streaming and
non-sequential plugins and hosts are probably in order...

I've included a Default field in the hints section, but I've not included
an XML GUI request function - this is because I'm not yet sure this is the
right place to get XML from. My instinct is that the XML should be in a
separate text file including a reference to the plugin library. I'm
flexible on this.

I've built an example reverse plugin and I can mail this to anyone
interested. This is untested as yet as I've not updated applyplugin etc to
use the new API. Supporting non-sequential plugins requires a bit of a
rewrite...

--Richard

/* ladspa.h

   Version 1.1[dev]. Copyright 2000 Richard W.E. Furse, Paul
   Barton-Davis, Stefan Westerfeld. */

#ifndef LADSPA_INCLUDED
#define LADSPA_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

/***********************************************************************
******/

/* Overview:

   There is a large number of synthesis packages in use or development
   on the Linux platform at this time. This API (`The Linux Audio
   Developer's Simple Plugin API') attempts to give programmers the
   ability to write simple `plugin' audio processors in C/C++ and link
   them dynamically (`plug') into a range of these packages (`hosts').
   It should be possible for any host and any plugin to communicate
   completely through this interface. The LADSPA plugin API is free to
   use.

   This API is deliberately short and simple. To achieve compatibility
   with a range of exciting Linux sound synthesis packages it attempts
   to find the `greatest common divisor' in their logical
   behaviour. Having said this, certain limiting decisions are
   implicit, notably the use of a fixed type (LADSPA_Data, see below)
   for all data transfer and the absence of a parameterised
   `initialisation' phase.

   Version 1 of this API required all plugins to perform in a (causal)
   streaming context. Version 1.1 is backwards binary compatible and
   adds extensions to allow plugins non-sequential (random,
   non-causal) access to input data. This is required by specialised
   plugins such as sample-based synth elements and `time-morphing'
   effects such as reverse, varispeed and some granular techniques.

   In the normal streaming context a plugin is expected to accept a
   stream of audio and control information cut into `blocks'
   corresponding to a time interval measured in samples. When the
   plugin is `run' (using run() or run_adding()) it writes out audio
   and control information in blocks of equivalent size. For instance,
   at a 44.1kHz sample rate, if the plugin were to process a block
   corresponding to 0.01s of real-time, the plugin will read and write
   blocks of audio that all contain 441 samples. Input controls take
   single values for the duration of the block and single values are
   written to output controls. The block size may be varied by the
   host and the host may wish to use small block sizes when control
   values are changing quickly.

   Plugins are expected to distinguish between control and audio
   data. Plugins have `ports' that are inputs or outputs for audio or
   control data. Audio data is communicated using arrays of
   LADSPA_Data. Control data is communicated using single LADSPA_Data
   values. The plugin may assume that all its input and output ports
   have been connected to the relevant data location (see the
   `connect_port()' function below) before it is asked to run.

   This block approach is very amenable to processing of real-time
   streams, however some unusual plugins require more sophisticated
   access to the audio and control information that is fed to it. For
   instance, a `reverse' effect requires access to audio that has not
   yet happened. In general this is impossible, but the rules change
   for pre-recorded and synthesised sound. To handle this, LADSPA
   includes an extension that allows a plugin to request
   `non-sequential' access of its inputs. These plugins cannot be used
   in all contexts. Non-sequential plugins are accessed in a slightly
   different way to streamed plugins.

   Plugins reside in shared object files suitable for dynamic
   linking. The file provides a number of `plugin descriptors' that
   can be used to instantiate actual plugins (sometimes known as
   `plugin instances') that can be connected together to perform
   tasks.

   This API contains very limited error-handling. */

/***********************************************************************
******/

/* Fundamental data type passed in and out of plugin. This data type
   is used to communicate audio samples and control values. It is
   assumed that the plugin will work sensibly given any numeric input
   value although it may have a preferred range (see hints below). */

typedef float LADSPA_Data;

/***********************************************************************
******/

/* Special Plugin Properties:

   Optional features of the plugin type are encapsulated in the
   LADSPA_Properties type. This is assembled by ORing individual
   properties together. */

typedef int LADSPA_Properties;

/* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a
   real-time dependency (e.g. listens to a MIDI device) and so its
   output must not be cached or subject to significant latency. */
#define LADSPA_PROPERTY_REALTIME 0x1

/* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin
   may cease to work correctly if the host elects to use the same data
   location for both input and output (see connect_port()). This
   should be avoided as enabling this flag makes it impossible for
   hosts to use the plugin to process audio `in-place.' This flag is
   almost always required by non-sequential plugins. */
#define LADSPA_PROPERTY_INPLACE_BROKEN 0x2

/* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin
   is capable of running not only in a conventional host but also in a
   `hard real-time' environment. To qualify for this the plugin must
   satisfy all of the following:

   (1) The plugin must not use malloc(), free() or other heap memory
   management within its run() or run_adding() functions. All new
   memory used in these functions must be managed via the stack. These
   restrictions only apply to the `run' functions.

   (2) The plugin will not attempt to make use of any library
   functions with the exceptions of functions in the ANSI standard C
   and C maths libraries, which the host is expected to provide.

   (3) The plugin will not access files, devices, pipes, sockets, IPC
   or any other mechanism that might result in process or thread
   blocking.

   (4) The plugin will take an amount of time to execute a run() or
   run_adding() call approximately of form (A+B*SampleCount) where A
   and B depend on the machine and host in use. This amount of time
   may not depend on input signals or plugin state. The host is left
   the responsibility to perform timings to estimate upper bounds for
   A and B. */
#define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4

/* This property indicates that the plugin is non-sequential (see the
   LADSPA_NonSequentialAccessControl structure and
   ladspa_nonsequential_descriptor() function below). */
#define LADSPA_PROPERTY_NONSEQUENTIAL 0x8

/* This property only applies to non-sequential plugins (see the
   LADSPA_NonSequentialAccessControl structure below). It indicates that
the
   plugin (e.g. a `reverse' plugin) needs to know when its
   non-sequential inputs finish. Non-sequential plugins that declare
   this flag are guaranteed that the host will provide a InputLength
   value within the LADSPA_NonSequentialAccessControl structure passed
   to it. */
#define LADSPA_PROPERTY_REQUIRES_INPUT_LENGTH 0x10

#define LADSPA_IS_REALTIME(x) \
        ((x) & LADSPA_PROPERTY_REALTIME)
#define LADSPA_IS_INPLACE_BROKEN(x) \
        ((x) & LADSPA_PROPERTY_INPLACE_BROKEN)
#define LADSPA_IS_HARD_RT_CAPABLE(x) \
        ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE)
#define LADSPA_IS_NONSEQUENTIAL(x) \
        ((x) & LADSPA_PROPERTY_NONSEQUENTIAL)
#define LADSPA_IS_SEQUENTIAL(x) \
        (!((x) & LADSPA_PROPERTY_NONSEQUENTIAL))
#define LADSPA_REQUIRES_INPUT_LENGTH(x) \
        ((x) & LADSPA_REQUIRES_PROPERTY_INPUT_LENGTH)

/***********************************************************************
******/

/* Plugin Port Properties:

   Plugins have `ports' that are inputs or outputs for audio or
   data. Ports can communicate arrays of LADSPA_Data (for audio
   inputs/outputs) or single LADSPA_Data values (for control
   input/outputs). This information is encapsulated in the
   LADSPA_PortDescriptor type which is assembled by ORing individual
   properties together.

   Note that a port must be an input or an output port but not both
   and that a port must be a control or audio port but not both. */

typedef int LADSPA_PortDescriptor;

/* Property LADSPA_PORT_INPUT indicates that the port is an input. */
#define LADSPA_PORT_INPUT 0x1

/* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */
#define LADSPA_PORT_OUTPUT 0x2

/* Property LADSPA_PORT_CONTROL indicates that the port is a control
   port. */
#define LADSPA_PORT_CONTROL 0x4

/* Property LADSPA_PORT_AUDIO indicates that the port is a audio
   port. */
#define LADSPA_PORT_AUDIO 0x8

/* The property LADSPA_PORT_NONSEQUENTIAL can only be used on input
   ports on non-sequential plugins (see the
   LADSPA_NonSequentialAccessControl structure below). It may be used
   with control or audio input ports. It indicates that the data
   connected to this port should be changed when the
   LADSPA_NonSequentialAccessControl structure's seek() function is
   used (see below). This property may only be used with
   non-sequential plugins, which also must indicate property
   LADSPA_PROPERTY_NONSEQUENTIAL. */
#define LADSPA_PORT_NONSEQUENTIAL 0x10

#define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT)
#define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT)
#define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL)
#define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO)
#define LADSPA_IS_PORT_NONSEQUENTIAL(x) ((x) & LADSPA_PORT_NONSEQUENTIAL)
#define LADSPA_IS_PORT_SEQUENTIAL(x) (!((x) &
LADSPA_PORT_NONSEQUENTIAL))

/***********************************************************************
******/

/* Plugin Port Range Hints:

   The host may wish to provide a representation of data entering or
   leaving a plugin (e.g. to generate a GUI automatically). To make
   this more meaningful, the plugin should provide `hints' to the host
   describing the usual values taken by the data.

   Note that these are only hints. The host may ignore them and the
   plugin must not assume that data supplied to it is meaningful. If
   the plugin receives invalid input data it is expected to continue
   to run without failure and, where possible, produce a sensible
   output (e.g. a high-pass filter given a negative cutoff frequency
   might switch to an all-pass mode).

   Hints are meaningful for all input and output ports but hints for
   input control ports are expected to be particularly useful.

   Hint information is encapsulated in the
   LADSPA_PortRangeHintDescriptor type which is assembled by ORing
   individual hint types together. Hints may require further
   LowerBound, UpperBound and Default information.

   All the hint information for a particular port is aggregated in the
   LADSPA_PortRangeHint structure. Note that the size of this
   structure has increased since LADSPA version 1, with which it is
   otherwise binary compatible. */

typedef int LADSPA_PortRangeHintDescriptor;

/* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field
   of the LADSPA_PortRangeHint should be considered meaningful. The
   value in this field should be considered the (inclusive) lower
   bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
   specified then the value of LowerBound should be multiplied by the
   sample rate. */
#define LADSPA_HINT_BOUNDED_BELOW 0x1

/* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field
   of the LADSPA_PortRangeHint should be considered meaningful. The
   value in this field should be considered the (inclusive) upper
   bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
   specified then the value of UpperBound should be multiplied by the
   sample rate. */
#define LADSPA_HINT_BOUNDED_ABOVE 0x2

/* Hint LADSPA_HINT_TOGGLED indicates that the data item should be
   considered a Boolean toggle. Data less than or equal to zero should
   be considered `off' or `false,' and data above zero should be
   considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in
   conjunction with any other hint except
   LADSPA_HINT_PROVIDES_DEFAULT. */
#define LADSPA_HINT_TOGGLED 0x4

/* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds or default
   specified should be interpreted as multiples of the sample
   rate. For instance, a frequency range from 0Hz to the Nyquist
   frequency (half the sample rate) could be requested by this hint in
   conjunction with LowerBound = 0 and UpperBound = 0.5. Hosts that
   support bounds and defaults at all must support this hint to retain
   meaning. */
#define LADSPA_HINT_SAMPLE_RATE 0x8

/* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the
   user will find it more intuitive to view values using a logarithmic
   scale. This is particularly useful for frequencies and gains. */
#define LADSPA_HINT_LOGARITHMIC 0x10

/* Hint LADSPA_HINT_INTEGER indicates that a user interface would
   probably wish to provide a stepped control taking only integer
   values. Any bounds set should be slightly wider than the actual
   integer range required to avoid floating point rounding errors. For
   instance, the integer set {0,1,2,3} might be described as [-0.1,
   3.1]. */
#define LADSPA_HINT_INTEGER 0x20

/* Hint LADSPA_HINT_DEFAULT indicates that a default value is
   available in the Default field of the LADSPA_PortRangeHint. The
   value is used typically to initialise a GUI into a sensible
   starting configuration. If LADSPA_HINT_SAMPLE_RATE is also
   specified then the value of Default should be multiplied by the
   sample rate. */
#define LADSPA_HINT_PROVIDES_DEFAULT 0x40

#define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) &
LADSPA_HINT_BOUNDED_BELOW)
#define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) &
LADSPA_HINT_BOUNDED_ABOVE)
#define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED)
#define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE)
#define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC)
#define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER)
#define LADSPA_IS_HINT_PROVIDING_DEFAULT ((x) &
LADSPA_HINT_PROVIDES_DEFAULT)

typedef struct _LADSPA_PortRangeHint {

  /* Hints about the port. */
  LADSPA_PortRangeHintDescriptor HintDescriptor;

  /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When
     LADSPA_HINT_SAMPLE_RATE is also active then this value should be
     multiplied by the relevant sample rate. */
  LADSPA_Data LowerBound;

  /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When
     LADSPA_HINT_SAMPLE_RATE is also active then this value should be
     multiplied by the relevant sample rate. */
  LADSPA_Data UpperBound;

  /* Meaningful when hint LADSPA_HINT_PROVIDES_DEFAULT is active. When
     LADSPA_HINT_SAMPLE_RATE is also active then this value should be
     multiplied by the relevant sample rate. */
  LADSPA_Data Default;

} LADSPA_PortRangeHint;

/***********************************************************************
******/

/* Plugin Handles:

   This plugin handle indicates a particular instance of the plugin
   concerned. It is valid to compare this to NULL (0 for C++) but
   otherwise the host should not attempt to interpret it. The plugin
   may use it to reference internal instance data. */

typedef void * LADSPA_Handle;

/***********************************************************************
******/

/* Non-Sequential Access Control:

   This structure is used by non-sequential plugins. It is not
   required when developing or hosting conventional streaming plugins.

   The host provides this structure to the plugin through the
   connect_nonsequential_access_control() function (see below). This
   must be done before the plugin is activated. The structure allows
   the plugin to select what input data is provided to it through its
   non-sequential inputs. */

typedef struct _LADSPA_NonSequentialAccessControl {

  /* The number of samples of input data available on all
     non-sequential inputs. This is optional except for plugins
     declaring LADSPA_PROPERTY_REQUIRES_INPUT_LENGTH. When a input
     length is not provided a 0 is used. Note that this is not the
     only mechanism by which a non-sequential plugin is shown the end
     of its input stream. Short reads from the seek() call (below) may
     also indicate this. */
  unsigned long InputLength;

  /* This function allows the plugin to tell the host what input data
     should be provided to its non-sequential inputs. As part of the
     LADSPA_NonSequentialAccessControl structure, this function is
     provided by the host. Non-sequential ports are indicated using
     the LADSPA_PORT_NONSEQUENTIAL flag.

     For normal sequential sockets data is provided block by block
     starting at the beginning. In contrast, non-sequential sockets
     can provide audio corresponding to the past and future. For
     instance, a `reverse' plugin will read from the end of its input
     stream to produce its first block of output.

     seek() may only be called from within run_nonsequential() or
     run_nonsequential_adding(). Once the plugin has been activated,
     seek() must be called before any data is read from non-sequential
     ports. It is not necessary to call this function every run
     function if the previous setting is suitable for subsequent
     calls. The host may call the plugin's connect_port() function
     during a seek() call for non-sequential inputs.

     The Control parameter indicates the structure on which the seek()
     function was provided.

     The Offset parameter indicates the point in time (measured in
     samples) to which data on input sockets should be made to
     correspond. This value is relative to the start of processing,
     not to the current time. If a plugin read from 0 initially and
     then maintained an internal counter that was incremented by the
     block size each time it was run then input streams would be read
     sequentially.

     The SampleCount here requests the amount of data that the plugin
     would like to have provided on its input ports. This applies to
     both audio and control inputs. For audio inputs, this requests
     the number of samples of audio provided. For control inputs, this
     requests the length of the time interval over which the control
     value must be valid.

     The host may override this SampleCount value and use a lower
     number for a number of reasons, for instance performance, end of
     input data or a control value change. The final value provided by
     the host is provided as the return value of this function. The
     function may return 0, indicating that the request is at or
     beyond the end of the input data. Note that when an InputLength
     value is provided the seek() return values must indicate a
     consistent end. */
  unsigned long (*seek)
    (const struct _LADSPA_NonSequentialAccessControl * Control,
     unsigned long Offset,
     unsigned long SampleCount);

} LADSPA_NonSequentialAccessControl;

/***********************************************************************
******/

/* Descriptor for a Type of Plugin:

   This structure is used to describe a plugin type. It provides a
   number of functions to examine the type, instantiate it, link it to
   buffers and workspaces and to run it.

   Note that the size of this structure has increased since LADSPA
   version 1, with which it is otherwise binary compatible. */

typedef struct _LADSPA_Descriptor {

  /* 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. */
  unsigned long UniqueID;

  /* 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. */
  const char * Label;

  /* This indicates a number of properties of the plugin. */
  LADSPA_Properties Properties;

  /* This member points to the null-terminated name of the plugin
     (e.g. "Sine Oscillator"). */
  const char * Name;

  /* 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 * Maker;

  /* 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. */
  const char * Copyright;

  /* This indicates the number of ports (input AND output) present on
     the plugin. */
  unsigned long PortCount;

  /* This member indicates an array of port descriptors. Valid indices
     vary from 0 to PortCount-1. */
  const LADSPA_PortDescriptor * PortDescriptors;

  /* This member indicates an array of null-terminated strings
     describing ports (e.g. "Frequency (Hz)"). Valid indices vary from
     0 to PortCount-1. */
  const char * const * PortNames;

  /* This member indicates an array of range hints for each port (see
     above). Valid indices vary from 0 to PortCount-1. */
  const LADSPA_PortRangeHint * PortRangeHints;

  /* 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. */
  void * ImplementationData;

  /* This member is a function pointer that instantiates a plugin. A
     handle is returned indicating the new plugin instance. The
     instantiation function accepts a sample rate as a parameter. The
     plugin descriptor from which this instantiate function was found
     must also be passed. This function must return NULL if
     instantiation fails.

     Note that instance initialisation should generally occur in
     activate() rather than here. */
  LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor *
Descriptor,
                               unsigned long
                    SampleRate);

  /* This member is a function pointer that connects a port on an
     instantiated plugin to a memory location at which a block of data
     for the port will be read/written. The data location is expected
     to be an array of LADSPA_Data for audio ports or a single
     LADSPA_Data value for control ports. Memory issues will be
     managed by the host. The plugin must read/write the data at these
     locations every time run() or run_adding() is called and the data
     present at the time of this connection call should not be
     considered meaningful.

     connect_port() may be called more than once for a plugin instance
     to allow the host to change the buffers that the plugin is
     reading or writing. These calls may be made before or after
     activate() or deactivate() calls and during seek() calls for
     non-sequential inputs.

     connect_port() must be called at least once for each port before
     run() or run_adding() is called. When working with blocks of
     LADSPA_Data the plugin should pay careful attention to the block
     size passed to the run function as the block allocated may only
     just be large enough to contain the block of samples.

     Plugin writers should be aware that the host may elect to use the
     same buffer for more than one port and even use the same buffer
     for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN).
     However, overlapped buffers or use of a single buffer for both
     audio and control data may result in unexpected behaviour. */
   void (*connect_port)(LADSPA_Handle Instance,
                        unsigned long Port,
                        LADSPA_Data * DataLocation);

  /* This member is a function pointer that initialises a plugin
     instance and activates it for use. This is separated from
     instantiate() to aid real-time support and so that hosts can
     reinitialise a plugin instance by calling deactivate() and then
     activate(). In this case the plugin instance must reset all state
     information dependent on the history of the plugin instance
     except for any data locations provided by connect_port(), gain
     set by set_run_adding_gain() and controls provided through . If
     there is nothing for activate() to do then the plugin writer may
     provide a NULL rather than an empty function.

     When present, hosts must call this function once before any `run'
     function is called for the first time. This call should be made
     as close to the run call as possible and indicates to real-time
     plugins that they are now live. Plugins should not rely on a
     prompt call to run after activate(). activate() may not be
     called again unless deactivate() is called first. Note that
     connect_port() may be called before or after a call to
     activate(). */
  void (*activate)(LADSPA_Handle Instance);

  /* This method is a function pointer that runs an instance of a
     streaming plugin for a block. Two parameters are required: the
     first is a handle to the particular plugin instance to be run and
     the second indicates the block size (in samples) for which the
     plugin instance will run.

     Note that if an activate() function exists then it must be called
     before run() or run_adding(). If deactivate() is called for a
     plugin instance then the plugin instance may not be reused until
     activate() has been called again.

     If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE
     then there are various things that the plugin should not do
     host must ignore this value (for backward compatibility).

     This function applies to conventional streaming plugins, for
     which it must be supplied. It is not used for non-sequential
     plugins, which must provide run_nonsequential() instead. */
  void (*run)(LADSPA_Handle Instance,
              unsigned long SampleCount);

  /* This method is a function pointer that runs an instance of a
     plugin for a block. This has identical behaviour to run() except
     in the way data is output from the plugin. When run() is used,
     values are written directly to the memory areas associated with
     the output ports. However when run_adding() is called, values
     must be added to the values already present in the memory
     areas. Furthermore, output values written must be scaled by the
     current gain set by set_run_adding_gain() (see below) before
     addition.

     run_adding() is optional. When it is not provided by a plugin,
     this function pointer must be set to NULL. When it is provided,
     the function set_run_adding_gain() must be provided also.

     This function applies to conventional streaming plugins. It is
     not used for non-sequential plugins, which may provide
     run_nonsequential_adding() instead. */
  void (*run_adding)(LADSPA_Handle Instance,
                     unsigned long SampleCount);

  /* This method is a function pointer that sets the output gain for
     use when run_adding() or run_nonseqential_adding() are called. If
     this function is never called the gain is assumed to default to
     1. Gain information should be retained when activate() or
     deactivate() are called.

     This function should be provided by the plugin if and only if the
     run_adding() or run_nonsequential_adding() function is
     provided. When it is absent this function pointer must be set to
     NULL. */
  void (*set_run_adding_gain)(LADSPA_Handle Instance,
                              LADSPA_Data Gain);

  /* This is the counterpart to activate() (see above). If there is
     nothing for deactivate() to do then the plugin writer may provide
     a NULL rather than an empty function.

     Hosts must deactivate all activated units after they have been
     run for the last time. This call should be made as close to the
     last run call as possible and indicates to real-time plugins that
     they are no longer live. Plugins should not rely on prompt
     deactivation. Note that connect_port() may be called before or
     after a call to deactivate().

     Deactivation is not similar to pausing as the plugin instance
     will be reinitialised when activate() is called to reuse it. */
  void (*deactivate)(LADSPA_Handle Instance);

  /* Once an instance of a plugin has been finished with it can be
     deleted using the following function. The instance handle passed
     ceases to be valid after this call.

     If activate() was called for a plugin instance then a
     corresponding call to deactivate() must be made before cleanup()
     is called. */
  void (*cleanup)(LADSPA_Handle Instance);

  /* This function is used in place of run() for non-sequential
     plugins. For these plugins it is mandatory.

     The prototype of this function differs from the previous run()
     function in that it returns the number of samples of audio
     output. When this is less than SampleCount this indicates that
     output has ended. The plugin should not be run again unless
     deactivate() and activate() are called. 0 is a valid return
     value, indicating simply that output ended on a block
     boundary. In this case, control outputs should not be assigned
     values. */
  unsigned long (*run_nonsequential)(LADSPA_Handle Instance,
                                     unsigned long SampleCount);

  /* This function is used in place of run_adding() for non-sequential
     plugins. It is optional. The prototype differs from run_adding()
     by returning the samples of audio output (see run_nonsequential()
     above). */
  unsigned long (*run_nonsequential_adding)(LADSPA_Handle Instance,
                                            unsigned long SampleCount);

  /* This function applies only to non-sequential plugins. It is used
     by the host to connect a LADSPA_NonSequentialAccessControl
     structure (see above) to the plugin. This structure provides
     information and callbacks to the plugin that allow it to select
     the input data that is provided to it through its non-sequential
     inputs.

     This function may not be used while the plugin is activated. The
     host must call this function before an initial call to
     activate(). The structure may not be changed while connected. */
  void (*connect_nonsequential_access_control)
  (LADSPA_Handle Instance,
   const LADSPA_NonSequentialAccessControl * Control);

} LADSPA_Descriptor;

/***********************************************************************
******/

/* Accessing a Plugin: */

/* The exact mechanism by which plugins are loaded is host-dependent,
   however all most hosts will need to know is the name of shared
   object file containing the plugin types. To allow multiple hosts to
   share plugin types, hosts may wish to check for environment
   variable LADSPA_PATH. If present, this should contain a
   colon-separated path indicating directories that should be searched
   (in order) when loading plugin types.

   A plugin programmer must include a function called
   "ladspa_descriptor" with the following function prototype within
   the shared object file. This function will have C-style linkage (if
   you are using C++ this is taken care of by the `extern "C"' clause
   at the top of the file). This function provides access to the
   descriptor structures for conventional streaming plugins
   only. Non-sequential plugins are accessed through the
   ladspa_nonsequential_descriptor() function below.

   A host will find the plugin shared object file by one means or
   another, find the ladspa_descriptor() function, call it, and
   proceed from there.

   Plugin types are accessed by index (not ID) using values from 0
   upwards. Out of range indexes must result in this function
   returning NULL, so the plugin count can be determined by checking
   for the least index that results in NULL being returned. */

const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);

/* A plugin programmer may also include a function called
   "ladspa_nonsequential_descriptor" with the following function
   prototype within the shared object file. This function will have
   C-style linkage (if you are using C++ this is taken care of by the
   `extern "C"' clause at the top of the file).

   This function is optional and differs from ladspa_descriptor() in
   that it returns descriptors for non-sequential plugins only. All
   such plugins must indicate property
   LADSPA_PROPERTY_NONSEQUENTIAL. */

const LADSPA_Descriptor * ladspa_nonsequential_descriptor(unsigned long
Index);

/* Datatype corresponding to the ladspa_descriptor() and
   ladspa_nonsequential_descriptor() functions. */
typedef const LADSPA_Descriptor *
(*LADSPA_Descriptor_Function)(unsigned long Index);

/* This function must be provided by the plugin library. It must
   return the statically allocated string "1.1". Note that this
   function was not required in LADSPA version 1. */
const char * ladspa_version();

#define LADSPA_VERSION "1.1"

/***********************************************************************
******/

#ifdef __cplusplus
};
#endif

#endif /* LADSPA_INCLUDED */

/* EOF */


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

This archive was generated by hypermail 2b28 : Sat Dec 09 2000 - 02:13:20 EET