Intro
Hello there, if you’re reading this document then you’re likely trying to figure out how to work with existing LV2 plugins and understanding some of the details of the LV2 spec. This document assumes some cursory knowledge about prior plugin standards including LADSPA(link)/DSSI(link)/VST(link)/etc. At the end of reading this guide you should be comfortable with setting up a basic host which can process audio, MIDI, and control events using several of the LV2 utility libraries in C. If you’re looking for a C++ implementation, we’ll briefly explain how the information within this guide can be translated at the end of this article.
For the most part in this guide we’ll refer to the official API specifications for more clarifications, though several code examples will come from one of several simple hosts including jalv(link) which is the reference implementation, lv2file(link) (a simple wav file processor), lv2apply(), lv2ls(link), and …
What can LV2 plugins do?
talk about the raw basics of audio synthesis, audio effects, midi effects, and GUIs. Have a brief mention of extensions, but do NOT talk about them until later.
Perhaps mention the existance of .ttl files here and say xxx is abstracted away by yyy.
The LV2 Ecosystem
If you’re searching around for libraries related to LV2 you may come across a wide variety of them. This can include lilv(links), raul(for), suil(every), serd(one), sord(of the), LV2 toolkit(libraries), and a few others. Fortunately building a basic host is not that difficult and will primarily build off of lilv.
Talk about the other components as need be
How can you load a LV2 plugin?
So, now that we know that we’re using lilv, how can we load a simple plugin. For this let’s try to load one of the basic sample plugins eg-amp. Plugins within LV2 are loaded based upon URIs, so in the case of the eg-amp plugin LV2 names it http://lv2plug.in/plugins/eg-amp. (perhaps a brief footnote on why this is the case, but nothing more)
First let’s verify that this plugin is installed on your system
void list_plugins(void) { LilvWorld *world = lilv_world_new(); lilv_world_load_all(world); const LilvPlugins *plugins=lilv_world_get_all_plugins(lilvworld); LilvIter *plug_itr = lilv_plugins_begin(plugins); for(int i=0; i<lilv_plugins_size(plugins); ++i) { LilvPlugin *plugin = lilv_plugins_get(plugins, plug_itr); LilvNode *uri_node = lilv_plugin_get_uri(plugin); const char *uri_str = lilv_node_as_uri(uri_node); printf("plugin.uri = %s\n", uri_str); plug_itr = lilv_plugins_next(plugins, plug_itr); } some_teardown_code_that_I_didn_t_bother_to_implement(); } int main() { list_plugins(); }
You can compile this snippet via XXX. If you need some help getting the dependencies setup then please see appendix A (this appendix should describe setup steps for the popular dev distros which at the moment are (IMO) Ubuntu & Arch). This code will open the lilv library and iterate through all the plugins available to the LV2 host. As long as you can see http://lv2plug.in/plugins/eg-amp in the output, then we’re all ready to go to the next step, putting a few samples into the plugin.
LilvPlugin *get_the_plugin(void) {} xxx *create_plugin_instance(plugin, ...) {} //Activate instance //instance run //Cleanup
At this point we’ve created a plugin instance, activated it, and run it, but how do we send data to it and get the results?
That brings us to the concept of LV2 ports.
-
Input
-
Output
-
Audio
-
Control (we’ll get to this later)
-
Etc (we’ll get to this later)
void connect_input_output_buffer() {...}
With this connection in place we can connect the input an output data from the host:
//feed in dummy data before processing //read out the same dummy data (assuming that eg-amp defaults to unison gain)
Great, we now have a plugin running and processing data within our trivial host
How do you control a LV2 plugin?
This brings us to how you can interact with control ports, …
LV2 Extensions
The core of LV2 does A, B, & C, but by design the specification makes it possible for hosts to implement extensions that the plugins can make use of. A common one is X. Let’s walk through the implementation of this extension and what happens when plugin hosts have the functionality and when they do not have it. For this example we’re going to use the X plugin which you can download from http://…;
Where to go from here?
At this point in the guide you should have a rough idea as to what components are needed for a LV2 host and how to assemble them. There’s still plenty more that can be done with LV2 and knowing about the available resources can make this a much easier process.
Example hosts:
-
jalv - recommended for learning a,b,c
-
lv2file - largely discussed within this guide
-
ardour - see link to small part of the git repo to understand how X is used in a large host as well as A,B,C to understand a few extensions
Other interesting projects:
-
LV2 mailing list
-
LV2 IRC chat
-
etc
Appendix A: LV2 dependency setup
Apt get yada yada Compiler tweak abc,
pacman xxx