Linux DevCenter    
 Published on Linux DevCenter (http://www.linuxdevcenter.com/)
 See this if you're having trouble printing code examples


Linux Audio Plug-Ins: A Look Into LADSPA

by Dave Phillips
02/02/2001

Plugging in...

As users, we choose specific applications because their features suit our purposes. As we become more familiar with a program, we want more features added to it, and of course we want it to run faster and smoother. Developers want to serve the needs of end-users, but increasing the internal complexity of an application is not necessarily a good thing, and programmers and users alike recognize the undesirability of feature creep and code bloat.

Nevertheless, we all want more cool and useful features in our software, giving rise to a dilemma: How do we balance the number and complexity of features against the complexity and manageability of the larger-scale program design?

A flexible architecture that allows plug-ins is an elegant solution to this problem, presenting the end-user with a mechanism to control at least some aspects of a program's feature set while giving program developers the opportunity to focus their energy toward creating flexible core engines and program frameworks. In addition, designers of plug-ins can work on developing their processing algorithms without the distraction of resolving interface or operating system dependencies. Everyone wins with plug-ins.

What is a plug-in anyway?

A plug-in is a software module that adds new functions or extensions to a host application, without the need to recompile the program. The plug-in functions are stored within a shared object file (*.so in Linux, *.dll in Windows) that may contain one or several plug-ins. The application provides the entry points to dock an object, and the new functions are immediately available. The user accesses the plug-in as a normal part of the host's interface.

Linux users are perhaps most familiar with the plug-in architectures for the GIMP image processor and for the XMMS media player. These applications provide developers with simple plug-in programming frameworks, while providing users with transparent interfaces for managing and applying third-party extensions.

GIMP and XMMS are wonderful programs and their plug-in collections are impressive. However, the plug-ins designed for these programs will work only with their intended applications and not others. Obviously a more universal plug-in architecture would be a very good thing: Developers could be freed from rewriting their code to accommodate different plug-in specifications; various applications could share the same resources; and users could build libraries of plug-ins to use with their favorite plug-in-friendly applications.

Such a solution already exists in the Mac and Windows audio software worlds in the form of the VST plug-in architecture. VST has been widely accepted as the de facto standard for audio plug-ins, with support coming from almost every major audio software house. Numerous collections of VST plug-ins are available over the Internet. Some are wonderful; some are not so wonderful. Some cost money while others are free. But almost all of these plug-ins will only work in Windows or Mac OS.

The special benefits of sound software plug-ins include interesting extensions such as digital signal processing (reverberation, chorusing and flanging effects, amplitude and ring modulation, dynamics processing, etc.), software synthesis (waveform and wavetable generators), mixing and balancing modules, and even composition-oriented utilities such as sequencers and random-number generators.

Several Linux audio applications support plug-ins; however, like GIMP and XMMS, their plug-in architectures are application-specific and do not provide a generalized plug-in API (application program interface) for Linux audio software. In the early stages of LADSPA development, some members of the LAD group contacted the Steinberg company in hopes of porting the VST architecture to Linux; alas, they got no joy.

Steinberg's license does not permit the redistribution of modified versions of its freely available VST SDK (a situation that could be neatly resolved if they adopted the GPL); however, a greater problem is that most VST plug-ins rely either on the native interface or libvstgui, a graphic interface library that has not been implemented in any of the popular GUI toolkits for Linux.

Even this reliance could be overcome with a new Linux implementation of libvstgui, and although the documentation for libvstgui fully specifies the API and even includes some source, this is a substantial programming effort that nobody has been willing to undertake to date. As a result, despite its theoretical portability, the VST API remains tied to the Windows and Mac interfaces, leaving Linux developers with a need for a simple standard for writing audio plug-ins. Enter LADSPA -- the Linux Audio Developer's Simple Plug-in API.

What's LADSPA ?

The original incentive for LADSPA development evolved from discussions that took place on the LAD (Linux Audio Developers) mailing list from late 1999 to early 2000. Paul Davis, Richard W.E. Furse, and Stefan Westerfield were major contributors to the first definition of ladspa.h, and in April 2000, Richard Furse announced version 1. The version level of the SDK (software development kit) now stands at 1.09, discussion and development continue to evolve, and the library of available plug-ins has grown appreciably, along with the number of LADSPA-friendly hosts. Support for LADSPA is clearly thriving and should become a consideration in any Linux audio software design.

LADSPA's design is based upon the extensive research that has already gone into applications such as Csound and other MusicV software synthesis environments. The LADSPA architects have provided a lightweight, flexible API based upon those long-established technologies and have created a plug-in architecture as useful for software sound synthesis and mixing as it is for modular effects processing.

The LADSPA SDK currently consists of the ladspa.h header file (which defines the application program interface), ten example plug-ins, and three utility programs. We'll begin our look into LADSPA by setting up the SDK, then we'll compile and test the utilities with some of the example plug-ins.

Getting into the SDK

First, go to the LADSPA home page to pick up the latest SDK. Download the tarball (ladspa_sdk.tgz) to your $HOME directory, unpack it with tar xzvf ladspa_sdk.tgz. Next go into your new LADSPA_SDK/src directory and run make to build the sample plug-ins and utilities. Compiling is straightforward and requires no special libraries or other dependencies. When the compiler is finished, become root (su root) and run make install. Set the LADSPA_PATH environment variable with this command:

export LADSPA_PATH=/usr/local/lib/ladspa

Add that line to your shell start-up script (typically the .bash_profile or .bashrc file in your $HOME directory) for a permanent setting. You are now ready to test the sample plug-ins.

For developers, the core of the SDK is ladspa.h, a C/C++ header that defines the API following this outline:

I refer the interested reader to the link above for the entire file. In keeping with LADSPA's fundamental design, the header is short, simple, and well-documented with clear relevant comments throughout. Later we'll watch the API in action when we analyze a LADSPA plug-in.

These three utilities are included with the SDK:

First, run listplugins to see what plug-ins are installed in LADSPA_PATH (by default set to /usr/local/lib/ladspa):

[dlphilp@localhost dlphilp]$ listplugins

/usr/local/lib/ladspa/amp.so:
        Mono Amplifier (1048/amp_mono)
        Stereo Amplifier (1049/amp_stereo)
/usr/local/lib/ladspa/delay.so:
        Simple Delay Line (1043/delay_5s)
/usr/local/lib/ladspa/filter.so:
        Simple Low Pass Filter (1041/lpf)
        Simple High Pass Filter (1042/hpf)
/usr/local/lib/ladspa/noise.so:
        White Noise Source (1050/noise_white)
/usr/local/lib/ladspa/sine.so:
        Sine Oscillator (Freq:audio, Amp:audio) (1044/sine_faaa)
        Sine Oscillator (Freq:audio, Amp:control) (1045/sine_faac)
        Sine Oscillator (Freq:control, Amp:audio) (1046/sine_fcaa)
        Sine Oscillator (Freq:control, Amp:control) (1047/sine_fcac)

Note that the five shared object files contain a total of 10 plug-in effects.

Now analyze one of the listed plug-ins:

[dlphilp@localhost dlphilp]$ analyseplugin delay.so

Plugin Name: "Simple Delay Line"
Plugin Label: "delay_5s"
Plugin Unique ID: 1043
Maker: "Richard Furse (LADSPA example plugins)"
Copyright: "None"
Must Run Real-Time: No
Has activate() Function: Yes
Has deactivate() Function: No
Has run_adding() Function: No
Environment: Normal or Hard Real-Time
Ports:  "Delay (Seconds)" input, control, 0 to 5
        "Dry/Wet Balance" input, control, 0 to 1
        "Input" input, audio
        "Output" output, audio

And now let's apply the plug-in to a sound file. First, take a look at the syntax for applyplugin:

[dlphilp@localhost dlphilp]$ applyplugin            
Usage:  applyplugin [flags] <input Wave file> <output Wave file>
        <LADSPA plugin file name> <plugin label> <Control1> 
        <Control2>...
        [<LADSPA plugin file name> <plugin label> <Control1>
        <Control2>...]...
Flags:  -s <seconds>  Add seconds of silence after end of input file.

The plug-in file name is the actual name of the object file, in this case delay.so. The plug-in label is delay_5s, and there are two control ports. The ports are numbered from the top down, and they may be audio or control ports. A control port receives data values specified by the user or by a user-defined connection such as a MIDI controller.

Using the analysis information, the following command-line sequence will apply 3 seconds of delay to an input file, with a 50/50 balance of dry/wet signal and with 3 seconds added to the end of the input (to hear the delayed signal to its end), and then pipe the output file to a sound file player for immediate playback:

applyplugin -s 3 your_input.wav your_output.wav delay.so delay_5s 3 .5; play your_output.wav

By now you should be getting the hang of how a LADSPA plug-in is used, so let's look more closely into the code behind delay.so and see how it works.

Inside a simple LADSPA plug-in

The C code for delay.so resides in $HOME/LADSPA_SDK/src/plugins and was written by Richard Furse. I've condensed its design into an outline here, and the interested reader should read delay.c in its entirety for the details of this plug-in's structure.

Delay.c follows this relatively simple plan:

Of course the actual code is more complex, but it really does follow the straightforward outline given above. Let's take a quick peek at Richard's sources to see how the input data gets into the plug-in and how it gets processed by the delay line.

The following code excerpt illustrates how each of the four ports within the delay line's structure (the delay time, the wet/dry balance, and the audio I/O) connects to a data location:

/* Connect a port to a data location. */
void
connectPortToSimpleDelayLine(LADSPA_Handle Instance,
                             unsigned long Port,
                             LADSPA_Data * DataLocation) {

  SimpleDelayLine * psSimpleDelayLine;

  psSimpleDelayLine = (SimpleDelayLine *)Instance;
  switch (Port) {
  case SDL_DELAY_LENGTH:
    psSimpleDelayLine->m_pfDelay = DataLocation;
    break;
  case SDL_DRY_WET:
    psSimpleDelayLine->m_pfDryWet = DataLocation;
    break;
  case SDL_INPUT:
    psSimpleDelayLine->m_pfInput = DataLocation;
    break;
  case SDL_OUTPUT:
    psSimpleDelayLine->m_pfOutput = DataLocation;
    break;
  }
}

Once the connections have been established, the data is ready for processing via this code block:

/* Run a delay-line instance for a block of SampleCount samples. */
void
runSimpleDelayLine(LADSPA_Handle Instance,
                   unsigned long SampleCount) {

  LADSPA_Data * pfBuffer;
  LADSPA_Data * pfInput;
  LADSPA_Data * pfOutput;
  LADSPA_Data fDry;
  LADSPA_Data fInputSample;
  LADSPA_Data fWet;
  SimpleDelayLine * psSimpleDelayLine;
  unsigned long lBufferReadOffset;
  unsigned long lBufferSizeMinusOne;
  unsigned long lBufferWriteOffset;
  unsigned long lDelay;
  unsigned long lSampleIndex;

  psSimpleDelayLine = (SimpleDelayLine *)Instance;

  lBufferSizeMinusOne = psSimpleDelayLine->m_lBufferSize - 1;
  lDelay = (unsigned long)
    (LIMIT_BETWEEN_0_AND_MAX_DELAY(*(psSimpleDelayLine->m_pfDelay))
     * psSimpleDelayLine->m_fSampleRate);

  pfInput = psSimpleDelayLine->m_pfInput;
  pfOutput = psSimpleDelayLine->m_pfOutput;
  pfBuffer = psSimpleDelayLine->m_pfBuffer;
  lBufferWriteOffset = psSimpleDelayLine->m_lWritePointer;
  lBufferReadOffset
    = lBufferWriteOffset + psSimpleDelayLine->m_lBufferSize - lDelay;
  fWet = LIMIT_BETWEEN_0_AND_1(*(psSimpleDelayLine->m_pfDryWet));
  fDry = 1 - fWet;

  for (lSampleIndex = 0;
       lSampleIndex < SampleCount;
       lSampleIndex++) {
    fInputSample = *(pfInput++);
    *(pfOutput++) = (fDry * fInputSample
                     + fWet * pfBuffer[((lSampleIndex + lBufferReadOffset)
                                        & lBufferSizeMinusOne)]);
    pfBuffer[((lSampleIndex + lBufferWriteOffset)
              & lBufferSizeMinusOne)] = fInputSample;
  }

  psSimpleDelayLine->m_lWritePointer
    = ((psSimpleDelayLine->m_lWritePointer + SampleCount)
       & lBufferSizeMinusOne);
}

It is beyond the scope of this article to perform an in-depth analysis of this block (it's the DSP heart of the plug-in), but I encourage novice plug-in developers to study Richard's code for a well-documented introduction.

The LADSPA architects deliberately designed a truly simple API to make it easy to write plug-ins.. However, the simplicity of the programming interface certainly does not limit the developer to writing only simple plug-ins. The currently available plug-in collections include some very complex plug-ins. Let's look at a few of those collections now.

LADSPA plug-in collections

The typical procedure for adding a plug-in to an application involves downloading the sources or a pre-compiled binary, then building and installing it just as you would do with any other application. Well-behaved LADSPA plug-in collections install themselves in the directories specified by LADSPA_PATH, and LADSPA-friendly hosts know to look there first for the available plug-ins.

Implementation details vary between hosts: Plug-ins may be listed in a menu or not at all within the host application, the plug-in's user-interface might be a nice GUI or a bare command-line, and some plug-ins are unusable on certain hosts. However, if the host recognizes the plug-in, then ideally the plug-in should behave as if it were an integral built-in part of the host. We'll look into some of those hosts, but first let's do a quick survey of some of the available sets of LADSPA plug-ins.

First you'll want to return to Richard Furse's LADSPA site and pick up the Computer Music Tool kit (CMT), a collection of more than 50 plug-ins free for your study and use. These plug-ins are available as a precompiled objects (cmt.so) or as source code. Compiling and installing the library object is a simple process: Download the source package to your $HOME directory, unpack it with tar xzvf cmt_src.tgz, enter your new CMT source directory, run make to build the plug-ins, and run (as root) make install to complete the installation.

The CMT has been planned as a complete plug-in tool kit for the electroacoustic musician: It already includes an impressive variety of synthesizer modules, filters, delay lines, envelope followers, and spatialization modules. The indefatigable Richard Furse has contributed the bulk of the plug-ins now in the tool kit, along with some excellent contributions from programmer David Bartold. Richard encourages plug-in writers to join the project and help expand the collection.

Developer Steve Harris has contributed a set of plug-ins available from his web site. The package is easy to build and install, and includes dynamics processors, distortion effects, chorus and flange, ring modulation, and pitch scaling. It also includes his Hermes filter, a remarkable plug-in with more than 50 control ports.

Stephane Conversy has translated some of the opcodes from Paul Davis's Quasimodo into LADSPA plug-ins. This set is very experimental and was created to showcase LADSPA's possibilities, so it should not be considered a finished package. Many of the Quasimodo opcodes derive from the Csound sound synthesis software, and the concept of turning them into plug-ins is quite novel. If you'd like to try some "edgier" plug-ins you can pick up Stephane's set here. Be sure to read the README file for the instructions on building the set: It isn't difficult at all, just a bit different.

You can test the plug-ins from these collections with your tools from the LADSPA SDK, or with a LADSPA-friendly host application. Let's take a look at some of those friendly hosts now.

LADSPA hosts

Note: The test platform for this section was a Pentium III 550 with lots of RAM, a decently fast and tuned IDE drive, a SoundBlaster SBLive Value soundcard (with ALSA and OSS/Linux drivers), and Linux kernel 2.4.0-test9 configured with Andrew Morton's low-latency patch. As with all audio software, performance will be best on a fast optimized system. Your results may vary.

In this part of our tour you'll see how some Linux audio applications manage and apply LADSPA plug-ins. LADSPA-friendly hosts include the following programs:

Both X and console applications can use LADSPA plug-ins so we'll test applications in both environments. You'll also use a "mini-network" GUI to build your own LADSPA plug-in. Let's start our tour of LADSPA hosts with a visit to Snd.

Snd

Bill Schottstaedt's Snd is a very powerful audio application available for a wide variety of *NIX platforms, including Alpha machines, SGI computers, Solaris, and machines running Linux and LinuxPPC. Snd presents a rather simple graphic interface, but it is truly deep audio software. Thanks to its LISP and Emacs heritage, the user interface can be completely customized; however, the audio processing engine is also extensible, providing hook-ups for extensions from many sources, including a Common LISP Music module (for MusicV-type sound synthesis), external programs such as Perry Cook's STK (the Synthesis Tool Kit, a set of C++ classes for music synthesis), Guile/Scheme code (via dynamically loaded shared objects or directly entered into Snd's Listener window), and LADSPA plug-ins, of course.

Note: To enable LADSPA support Snd must be compiled with the --with-ladspa configuration option.

Snd's LADSPA module was contributed by Richard Furse. It contains four basic support functions: an initialization search (init-ladspa), a list function (list-ladspa), a plug-in analyzer (analyse-ladspa), and the plug-in loader (apply-ladspa). LADSPA plug-ins are invoked in the Listener, Snd's interactive Guile\Scheme programming interface, following this syntax:

(apply-ladspa reader (plugin-library plugin-type [param1 [param2 ...]]) samples origin)

In Figure 1 we see these command parameters in the Listener:

(apply-ladspa (make-sample-reader 57264) (list "cmt" "delay_5s" .3 .5) 32556 "ibm.wav")

This sequence tells Snd to read a block of 32556 samples from the ibm.wav file, starting at sample number 57264, and apply the delay_5s LADSPA plug-in (Richard Furse's delay plug-in, also found in cmt.so) with a delay time of .3 seconds and a 50/50 dry/wet balance. Figure 2 shows the sound file after the effect has been applied.

If all that seems a bit cumbersome, bear in mind that the Listener works with standard Emacs key bindings, including those for text cut/copy/paste operations, and the Listener window area is itself very flexible about text entry. You may freely position the cursor for editing anywhere within the window, and a command can be repeated merely by clicking the cursor at the end of the previous entry and pressing Enter.

Alas, I don't have space to give Snd the attention it deserves. For now, I recommend downloading it, playing with it, and studying its copious and excellent documentation. And don't forget to try out all those LADSPA plug-ins.

Ecasound

Kai Vehmanen's ecasound accommodates the LADSPA plug-ins to extend its real-time signal processing options. Here's how ecasound plays a WAV file and applies the delay_5s effect to it while controlling one of the plug-in's parameters in real time with an external MIDI device:

ecasound -c -r -i:/home/dlphilp/soundfiles/wav/ibm.wav \
        -el:delay_5s,0.0,0.50 \
        -km:1,0.0,5.0,7,0 \
        -o:alsa,0,0

The flags set up the performance as follows:

Figure 3 displays ecasound's informative status report on the results of this command sequence.

This line:

-el:delay_5s,0.0,0.50

opens the delay_5s plug-in with the delay time initialized to 0.0 (its value will be dynamically controlled via MIDI) and the balance of wet and dry (effected and uneffected signals) set to 50/50. The next line:

-km:1,0.0,5.0,7,0

binds the first LADSPA plug-in effect parameter to MIDI controller #7 on channel 0 and maps the controller's range to values between 0.0 and 5.0.

I ran the example above with -i:alsa,0,0,0 for real-time audio input and controlled the delay time with a looping controller track on an external sequencer. I set my mixer to record from the CD channel, popped in a disc of poetry readings and enjoyed some rather interesting delay effects upon the spoken word.

terminatorX

Alexander König describes his terminatorX as "a real-time audio synthesizer that allows you to 'scratch' on digitally sampled audio data the way hiphop DJs scratch on vinyl records." Featuring multiple turntables, real-time effects, a sequencer, and a Gtk+ GUI, TerminatorX provides graphic controls for its own lowpass filter, echo, pitch, and pan settings. It also supplies the same sort of controls for LADSPA plug-ins.

Figure 4 shows terminatorX in its start-up state. In the control panel at the left of the display (the virtual turntable) you see a strip of controls for the built-in effects, plus a button labelled FX. Pressing that button will call a menu of the permissible LADSPA plug-ins (terminatorX currently supports only mono plug-ins), and selecting a plug-in will create a set of controls for it directly beneath the built-in effects controls. Note that multiple plug-ins can be installed per turntable.

terminatorX sets up virtual turntables for looping sound files and assigns various functions to the left-right/up-down movements of the mouse over a selected turntable's display. The mouse's virtual scratching then controls the sound's speed, volume, and pitch, as well as the parameters for the lowpass filter and the echo effect. Figure 5 shows a single turntable with a sound file loaded, the built-in effects minimized, and the delay_5s LADSPA plug-in installed and enabled.

You can create some very interesting sounds by combining the built-in effects with LADSPA plug-ins. In Figure 6 I've set up three turntables, assigned various functions to the mouse movements, and added a LADSPA plug-in for each turntable. This arrangement made for some wild sounds, and it must be noted that terminatorX handled the complexity without a hitch. Of course, running a Linux kernel patched for low-latency doesn't hurt performance.

As with Snd and ecasound, terminatorX is worthy of much deeper exploration. I highly recommend it to anyone interested in Linux audio applications: After all, there's a little Linux DJ in all of us, right?

Making a plug-in with GDAM

By this point we've taken a good look at LADSPA. You've met the API, analyzed a typical plug-in's C code, and installed a plug-in collection or two. We've seen how different hosts manage, present, and apply LADSPA plug-ins. Now let's write one of our own.

Did I hear you say that you're not an audio software programmer, or any kind of programmer at all? Or that you have no degrees in advanced mathematics and digital signal processing? Well, the authors of GDAM have provided just the thing for budding plug-in builders with other skillsets.

Programmers David Benson and Geoff Matters have created a graphic LADSPA plug-in designer called mininet. The mininet tool is part of Dave and Geoff's GDAM, a powerful DJ-style audio mixer and signal processor. It would be easy to spend the next few hours exploring GDAM's features, but for now we'll focus on its support for LADSPA.

As an audio processor, GDAM is a natural candidate as a LADSPA-friendly host. On startup GDAM looks in the default LADSPA_PATH and automatically loads the plug-ins it finds there. Those plug-ins are then available for use within GDAM's various players and processors.

GDAM's player windows include a strip of icons and buttons representing the native and LADSPA plug-in effects. The mininet utility is the next-to-last icon before the buttons [Figure 7]. This tool lets you connect various nodes together to create a signal processing path. The audio input and output nodes are hard-wired into the network, and it is not possible to add to or remove them. The other nodes can be signal modifiers such as delay lines and ring modulators, signal generators such as the noise and wavetable nodes, or signal mixing and balancing nodes. Any number of those nodes may be added or deleted from a network. Clicking on some nodes will open a set of parameter controls, others have fixed functions with no user-definable controls available. When you have arranged the nodes in the patterns you want, the mini-network is saved as a simple XML file. Finally, an external utility (ladspapluginmaker) converts the XML specifications into a C program (foo.c) and its associated header (foo.h) then directly compiles the C program into the new LADSPA plug-in object (foo.so).

Figure 8 illustrates a simple network designed to apply a fixed delay of 1 second to an input signal and send the delayed and original signals to the output. The delay node was added by left-clicking on the Delay button to the right of the workspace, then left-clicking again in the workspace to drop it there. Connections are made by dragging wires from outputs to inputs. Wires can be freely added and deleted, and as you can see in our example, a single input or output port accepts multiple connections.

Our simple example takes a single parameter value, the fixed amount of delay time applied to the input. The other nodes take no user-supplied values. After setting the delay time, all that's left to do here is press the Save button, name our new XML file, and save it. Next, open an xterm window, move to the directory where we saved the fixed_delay.xml file (you may want to create a directory just for your mininet XML files), and call ladspapluginmaker with the following command line:

ladspapluginmaker --input fixed_delay.xml 
    --output dp_fixed_delay_dir \
    --basename dp_fixed_delay --class FixedDelay \
    --description "1s Fixed Delay" --unique-id 100 \
    --build

Now we have a new directory named dp_fixed_delay_dir that contains dp_fixed_delay.c, dp_fixed_delay.h, and dp_fixed_delay.so. Copy the shared object file to your LADSPA_PATH directory and it's ready for use by your favorite LADSPA-friendly hosts. Incidentally, you can create only the C files by leaving off the --build option. All other options shown are mandatory.

The analyseplugin utility tells us these facts about our plug-in masterpiece:

[dlphilp@localhost gdam-0.933]$ analyseplugin dp_fixed_delay.so

Plugin Name: "1s Fixed Delay"
Plugin Label: "FixedDelay"
Plugin Unique ID: 100
Maker: "gdam ladspa plugin maker"
Copyright: "None"
Must Run Real-Time: No
Has activate() Function: Yes
Has deativate() Function: No
Has run_adding() Function: No
Environment: Normal
Ports:  "Input" input, audio
        "Output" output, audio

I plugged this effect into the virtual rack in Reiner Klenk's neat ladspaToy [Figure 9], ran a WAV file through it, and the plug-in worked perfectly. Far more complex networks can be created with the mininet tool, but I must leave that study as an exercise for the interested reader.

Recent LADSPA development issues

The LAD mailing list is the principal forum for the presentation and discussion of LADSPA development issues. Recent LADSPA-specific traffic has discussed issues concerning the possibility of non-sequential actions in a plug-in (for reverse or varispeed operations), the use of run_adding() versus run() in buffer scaling operations, the limitations of the HARD_RT_CAPABLE flag, and the use of LADSPA hints.

In the first section of this article, I mentioned the popularity of the Steinberg VST plug-in architecture on the Windows and Mac platforms. It has been pointed out that at least part of VST's success is due to the availability of a standard GUI tool kit on each of those platforms, simplifying the provision of hooks into the native graphic interface. Given the free availability of Motif, GTK, Qt, and other powerful Linux GUI toolkits, matters regarding graphic interfaces are more complicated for LADSPA developers.

The prospect of rewriting plug-ins to accommodate different tool kits defeats the purpose of the API. However, the use of XML as a descriptive medium has been discussed by LADSPA developers, and Paul Davis has proposed an XML DTD (document type definition) for approval by members of the LAD group. The discussions can be read in the LAD mailing list archives; Paul's DTD proposal can be read here.

Other Linux audio plug-in APIs

LADSPA is not the only player in the Linux audio plug-in world. The aRts project and David Olofson's MAIA are friendly competitors developing a more professional (i.e., more complex) audio plug-in API for Linux.

MAIA's developer has stated that his intention is to create an advanced Linux audio API equivalent to and surpassing the capabilities of the VST2 specification (an expansion of the original Steinberg VST API). However, at this time MAIA is still under heavy development; preliminary specifications may be read in the event.h file of the currently available software.

aRts is already well-known as the sound server for KDE2, but developer Stefan Westerfeld points out that the aRts plug-in API is a truly generalized interface independent of KDE. It must be noted though that aRts does depend upon another layer of abstraction (MCOP, the Multimedia Communications Protocol), and its success with plug-in writers remains to be seen.

Pulling the plug...

LADSPA has proven itself successful at implementing a simple and useful specification for Linux audio plug-ins, and the API continues to evolve. An excellent selection of LADSPA-based software already exists, more friendly hosts are on the way, and the simplicity of the API should promote development of new plug-in collections. I encourage developers to consider adding LADSPA support to their Linux audio software: As we have seen, the API is indeed a simple plug-in specification, easily implemented, and capable of real power and flexibility (see especially Steve Harris's Hermes Filter and Jezar's Freeverb3).

Fortunately there's no need for me to wait for all those new plug-ins: I'm heading off to a session with GDAM's mininet to build a collection of my own. You know, given that all the Linux software mentioned in this article is free and open-source, you could quickly be building yours too.

(And please, notify me if you do write any cool new plug-ins or a LADSPA-friendly host. I'll be happy to announce and list your software on the Linux Music & Sound Applications web site.)

LADSPA resources list

Other indispensable Linux audio resources

Dave Phillips maintains the Linux Music & Sound Applications Web site and has been a performing musician for more than 30 years.

Copyright © 2009 O'Reilly Media, Inc.