LV2 Support

Abstract


LV2 ("LADSPA Version 2") is an open plug-in architecture for signal processing plug-ins. It is designed to do everything that its predecessor LADSPA does, while being much easier for anyone to extend with new features.

Adding LV2 support to Audacity will let users apply LV2 effects to audio clips and, with support for the right extensions, use LV2 synthesizer plug-ins as powerful tone generators. LV2 also allows for categorisation of plug-ins in a hierarchy - this could be extended to the built-in effects in Audacity and used to display them in a more user-friendly way.

See http://lv2plug.in for more information on LV2.

Project documentation
For anyone who wants to look at and test the code there is some documentation here: LV2 Support/Project Docs

Progress
This pretty diagram shows how I'm using my time for the project. Labels on the horizontal axis are weeks, vertical are the tasks listed below. Grey  X s are the plan, coloured  X X  X s are actual progress. Red means that I'm just getting started on that task, orange means that I'm in the middle of it, and green means that it's pretty much done, just cleaning up. This diagram will be updated a couple of times every week.

              |  22  |  23  |  24  |  25  |  26  |  27  |  28  |  29  |  30  |  31  |  32  |  33  | _______________|===================================================================================| 1             | XXXXXX |      |      |      |      |      |      |      |      |      |      |      | _______________| XX XXXX | XX X  | X  X  |      |      |      |      |      |      |      |      |   X  | 2             |      | XXXXXX |      |      |      |      |      |      |      |      |      |      | _______________|   X  X | X     | X    |  X  X |      |      |      |      |      |      |      |      | 3             |      |      | XXXXXX | XXXXXX |      |      |      |      |      |      |      |      | _______________|     |  X  XX | X  XX | XXX  X |  X   | X    | X     |      |      |      |      |      | 4             |      |      |      |      | XXXXXX | XXXXXX |      |      |      |      |      |      | _______________|     |      |      |    XX | XX XX | X XXX | XXXX | X    |      |      | X    |      | 5             |      |      |      |      |      |      | XXXXXX | XXXXXX |      |      |      |   X  | _______________|     |      |      |      |      |      |      |  X   |      | X  XX  | X     |      | 6             |      |      |      |      |      |      |      |      | XXXXXX |      |      |      | _______________|     |      |      |      |      |      |      |      |      |      |   XX  X | X     | 7             |      |      |      |      |      |      |      |      |      | XXXXXX |      |      | _______________|     |      |      |      |      |      |      |      |      |      | X  X   X | X    | 8             |      |      |      |      |      |      |      |      |      |      | XXXXXX |      | _______________|     |      |      |      |      |      |      |      |      |      |  X  X  X |      | Finishing up  |      |      |      |      |      |      |      |      |      |      |      | XXXXXX | _______________|     |      |      |      |      |      |      |      |      |      |      |      | |===================================================================================| Notes         |1     |1 2   |1     |      |      |1     |1     |      |      |      |      |      |

Plan
This is how I'm planning to break down my work. The tasks below will be done in order, though some overlap may occur. Numbers 1, 2 and 3 form the early spinoff for this project and my first focus will be on getting those parts usable.




 * 1) Effect category support Add infrastructure in Audacity to allow categorisation of plug-ins and built-in effects. The user-visible part of this would be that the "Effects" menu would have submenus for the different categories instead of the current submenus named "plugins 1 - 15", "plugins 2 - 30" etc, making it easier to find plug-ins and figure out what they do. Since there may still be plug-ins that are not categorised there would also have to be an "Unsorted" submenu that could have the same submenu division as the current "Effects" menu.
 * 2) Categorise bundled effects Add support for categories to Nyquist and built-in effects and categorise all of them.
 * 3) LADSPA category support Add partial support for LRDF, a system of metadata for LADSPA plug-ins that includes plug-in categories. Not all LADSPA plug-in authors have written LRDF data files for their plug-ins, but most of the large packages have categorised plug-ins (SWH, TAP, CAPS).
 * 4) Basic LV2 support Add basic support for LV2 effect plug-ins, i.e. loading them, presenting them in the Effects menu (using their categories), generating control dialogs for them on request and applying them to audio regions. Once this is done users would be able to use the CALF LV2 effects, my Math plug-ins, and other LV2 effect plug-ins that generates audio output from audio input.
 * 5) LV2 synth support Add support for using LV2 synthesiser plug-ins, that generate audio output from MIDI input, as tone generators. This would include implementing partial support for the Event Port extension (for input ports only) and for sending MIDI events to event ports. The synthesiser plug-ins would be presented in the "Generate" menu, and the user would be able to set all their control parameters and the MIDI key, MIDI velocity, time between Note On and Note Off, and total time for the generated signal (since most synths don't go silent right away when receiving a Note Off but rather have a gradual release). Once this is done users would be able to use the CALF Monosynth, the CALF Organ, Sineshaper, Rudolf 556, Nekobee and other LV2 synth plug-ins as tone generators.
 * 6) Scale point support Add support for LV2 scalePoints, which are a part of the LV2 core specification and allows a plug-in author to label certain values for certain plug-in parameters, e.g. "Left" and "Right" for the values -1 and 1 for a stereo balance parameter. These labels would be displayed attached the widget for that parameter in the control dialog for that LV2 plug-in, making it easier for users to see what a particular parameter does.
 * 7) LV2 I18N support Add support for internationalisation for LV2 plug-in and parameter names (and scalePoint labels and category names). This would display these strings in the currently selected language, assuming that the plug-in author has added translations for that language. This would make the plug-in control dialogs and the plug-in names in the "Effects" and "Generate" menus blend in better with the rest of the UI, as well as making them easier to understand for non-English speakers.
 * 8) LV2 port group support Add support for the LV2 Port Group extension for input control ports. This allows plug-in authors to group related parameters in a plug-in together and add labels to the groups, for example the group "LFO 1" could contain amplitude and frequency parameters for the first LFO in the plug-in and the group "LFO 2" could contain the same for the second LFO. This would be presented in the plug-in control dialog by putting parameter controls belonging to the same group in wxStaticBox frames with the group name showing. This would make the plug-in control dialogs more structured and easier to read when there are lots of parameters.

Other
Some earlier LV2 work by me, unrelated to Audacity:
 * ll-plugins - a bunch of plug-ins and an experimental host
 * lv2-c++-tools - a set of C++ libraries and tools for easy plug-in hacking

2008-05-27: Modus operandi
Just a few notes about my setup, in case anyone would be interested.

Audacity uses CVS for revision control. I've decided to use my own local revision control so I can do small commits, create local branches, backtrack, cherry-pick patches etc without spamming the CVS repository. I use Git since I've recently used it for other things and really like it. Unfortunately there are no perfect Git <-> CVS sync tools - there is git-cvsimport which imports the history of a CVS repository into Git, from scratch or incrementally, and git-cvsexportcommit which generates a patch for a single Git commit, applies it to a separate CVS working directory, and optionally commits it.

So what I've done is to run git-cvsimport to retrieve the entire history of the audacity CVS module from 2001 to 2008. I ran into a problem - the audacity module is actually a virtual CVS module that redirects to audacity-src with lib-src as a subdirectory, which git-cvsimport</tt> couldn't handle. I solved that by first importing audacity-src</tt> and then lib-src</tt> separately, in a subdirectory of my Git repository for audacity-src</tt>. I can then run git-cvsimport</tt> in the repositories to fetch all changes from the CVS server into Git remote branches, see what everyone else is doing, and merge or cherry-pick into my working branches whenever I want.

For the other direction (Git -> CVS) I have a separate CVS checkout that I can run git-cvsexportcommit</tt> on when I have a sequence of local Git commits that I want to send to the CVS server, either as one CVS commit per Git commit or in batches.

Syncing Git repositories against the main Audacity repository will probably be much easier in the future if the code moves to SVN, the Git <-> SVN sync tools look much nicer. But for now we're stuck with CVS.

2008-06-04: Category support working
Sent the first patch for review to Chris yesterday, it implements support for effect categories and adds categories to the built-in effects and the bundled Nyquist plug-ins. I decided to use the LV2 standard categories as a model for Audacity and map other plug-in systems' categories to that (e.g. LRDF for LADSPA), but that can easily be changed in the future. The standard LV2 categories look like this:

plugin | |\_Utility | | |  |\_Converter | | |  |\_Analyser | | |   \_Mixer | |\_Generator | | |  |\_Instrument | | |   \_Oscillator | |\_Simulator | | |   \_Reverb (also subcategory of Delay) | |\_Delay | | |   \_Reverb (also subcategory of Simulator) | |\_Modulator | | |  |\_Phaser | | |  |\_Flanger | | |   \_Chorus | |\_Filter | | |  |\_Lowpass | | |  |\_Highpass | | |  |\_Bandpass | | |  |\_Comb | | |  |\_Allpass | | |   \_Equaliser |    | |     |\_Parametric |    | |      \_Multiband | |\_Spectral Processor | | |   \_Pitch Shifter | |\_Amplifier | |\_Distortion | | |   \_Waveshaper | \_Dynamics Processor |   |\_Compressor |   |\_Expander |   |\_Limiter |    \_Gate

The top LV2 category, "plugin", is not used in Audacity - all the categories that are direct subcategories of "plugin" in LV2 are considered "root categories".

LADSPA plug-ins (through LRDF) and LV2 plug-ins can define their own categories in their RDF data as subcategories of these, and it's up to the LADSPA/LRDF and LV2 loaders (which I will write) to add those categories to the EffectManager.

Categories will only show up in the Effect menu if they or any of their subcategories contain more than one effect. If they contain exactly one effect the category submenu will be replaced with a menu entry for that effect. There is some room for improvement here, for example it would be good to automatically collapse linear subgraphs to reduce the number of submenus (e.g. Dynamics Processor -> Compressor -> [ Compressor, Leveller ] to Dynamics Processor -> [ Compressor, Leveller ] ).

2008-06-05: LRDF categories sort of working
At least they are working on Debian, using system libraries, on my laptop: Screenshot

Some LADSPA plug-ins do not have category metadata installed (32 out of 254 on my system). I may write up some simple RDF files for those and send to their authors if I have time.

2008-06-12: LRDF categories committed
Still Linux only. I'll start adding libraries to lib-src/ after the sunday alpha.

You need to have headers and libraries for liblrdf installed, on Debian they are in the package liblrdf0-dev. If you for some reason would want to turn off LRDF support you can do that with the --without-liblrdf parameter to the configure script.

2008-07-04: LV2 support committed
Linux only, system libraries only - you need libslv2 installed. Quite a lot of bugs so far, hopefully they won't be that hard to squash.

2008-07-09: LV2 libraries added to lib-src
LV2 code added to lib-src (directories redland, liblrdf, slv2). The libraries build on Linux and Mac, but slv2 does not build on Windows yet (code is actually C99 which is not supported in Visual Studio).

How to test support on Mac and Windows
(copied from )

For liblrdf, you should define the preprocessor symbol USE_LIBLRDF in your config*.h and any installed LADSPA plug-ins that have associated RDF data will show up in the correct category submenu instead of under "Unsorted"...

..except they won't, because I'm only loading LADSPA RDF files by default on Linux so far - I didn't know the installation path for RDF data on other systems. You can set the environment variable LADSPA_RDF_PATH to point to the path(s) where the RDF files are installed, or you can add default paths in the code - the relevant part is src/effects/ladspa/LoadLadspa.cpp:184-193:

rdfPathVar = wxGetenv(wxT("LADSPA_RDF_PATH")); if (rdfPathVar != wxT("")) wxGetApp.AddMultiPathsToPathList(rdfPathVar, rdfPathList);

wxGetApp.AddUniquePathToPathList(wxT("/usr/share/ladspa/rdf"),                                    rdfPathList); wxGetApp.AddUniquePathToPathList(wxT("/usr/local/share/ladspa/rdf"),                                    rdfPathList);
 * 1) ifdef __WXGTK__
 * 1) endif

For SLV2, you should define the preprocessor symbol USE_SLV2 and compile and link src/effects/LoadLV2.cpp and src/effects/LV2Effect.cpp. This is still very buggy, but if you can compile the example plug-in at and put it in a LV2 plug-in directory ($(HOME)/Library/Audio/Plug-Ins/LV2 on Mac, anywhere that you add in the environment variable LV2_PATH on Windows) it should appear under "Unsorted" as "Simple amplifier" and there should be a line printed on startup that says that it was found.

SLV2 doesn't have any default search path on Windows, I'll write a patch for that. What would be a good set of system-wide and user paths for LV2 plug-ins? The LV2 docs only mention Linux and Mac, so we would be setting a precedent. "C:\Program Files\LV2 Plug-ins" ; "$(HOME)\My LV2 Plug-ins" ?