Skip to content

Instantly share code, notes, and snippets.

@fundamental
Created May 6, 2018 22:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fundamental/f918f6704f6c01cd22ab1c489ac28578 to your computer and use it in GitHub Desktop.
Save fundamental/f918f6704f6c01cd22ab1c489ac28578 to your computer and use it in GitHub Desktop.
LV2 Doc Sketch

Introduction to LV2, a Plugin Host Perspective

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment