From MOD Wiki
Jump to navigation Jump to search

This page describes how the LV2 plugin standard in integrated in the MOD platform.
It is not meant to give an overview of LV2 itself.

NOTE: WIP page, content still being added

Architecture overview

For LV2, MOD units have 2 points of interest.

First there is mod-host, which is the plugin host that actually loads LV2 plugin binaries and runs them.
mod-host runs integrated into JACK, so that processing and timing comes from it.
We use it as a quick way to get access to a multi-threaded modular environment, as each plugin inside mod-host gets its own JACK client. So the audio buffers come directly from JACK.
Both mod-host and LV2 plugins are loaded "in process", meaning if they crash everything crashes with it.
While mod-host is what loads plugins, it is not the session manager. That job is done by mod-ui.

mod-ui is the webserver that bridges between the (remote) web gui interface and the plugin host.
It acts as session manager, that is, mod-ui is the one that stores and loads user projects (named "Pedalboards" on the MOD platform).
To communicate with mod-host, a unix socket is used. Commands are passed from mod-ui to mod-host when actions are taken by the user on the web interface (like adding plugins, changing a parameter, etc). mod-host will in turn notify mod-ui when plugin-side events happen, such as value changes of LV2 control output ports.

Because mod-host (running inside jackd) and mod-ui are independent programs, both have to load LV2 metadata from disk.
This has not been a problem so far, as lilv is really quite fast in its ttl file scanning.
A side-effect from this separation is that, while a plugin crash will also crash JACK and bring down the audio, mod-ui remains unaffected and so does the user session. It is possible to reload the current pedalboard after a plugin crash and recover the previous state, because mod-ui is the session manager.

Common caveats

No desktop GUI

Typically plugin GUIs are made with the target native system in mind, for example Cocoa or X11. But because MOD units are embed devices, there is no graphical interface for plugins to use directly. In fact, X11 libraries are not even present on the linux system inside. If your plugin binary links to libX11, it will simply fail to load.
Frameworks like JUCE have bypassed this issue by loading libX11 on start, instead of linking to it. While this works, it is not an approach that we recommend pursuing. It is best to disable the desktop GUI altogether as it is never going to be used.

The MOD approach is to make GUIs using Web technologies (HTML, CSS and JavaScript) which are rendered by served by mod-ui and rendered by the browser on the client (remote) side.
No binaries are used for this, and JavaScript is optional (typically only needed if you have dynamically updated events that the webserver cannot handle automatically).

Full DSP / UI separation

Because no binaries are used to make GUIs, and GUIs are rendered separately from the audio/plugin side (unit runs the audio stuff, browser on a different PC runs graphical interface) this makes the DSP and GUI of a plugin completely separate things.
What this means for developers is that anything that the plugin GUI requires needs to go through the webserver first, and then passed by a few layers until it reaches audio/DSP side. You cannot simply take a pointer and call plugin methods from your GUI, you need to use APIs provided by the webserver in order to pass messages around.

This is more a caveat for developers wanting to do more than simple parameters.
If you do not require custom state, such as files or strings, feel free to ignore this part. :)


Printing statements from the plugin for debugging is possible, but perhaps not as you expect.
For obvious reasons you cannot just call `printf` from your plugin and expect things to happen..
Unless you stop and start jackd yourself inside the unit, prints have nowhere to go.

Luckily LV2 provides us with a logging mechanism through the LV2 log extension.
This extension is supported in mod-host. When you use lv2 log for "printing" a string the output is sent through mod-ui into any active browser window using JavaScript's console.debug/log/warn/error functions.
The LV2 log level is mapped directly to the equivalent console function (DEBUG as console.debug, WARNING as console.warn etc)
Just make sure to have your browser developer console open and prints from the plugin will be redirected there.

Note that per LV2 standard, the DEBUG log level is required to be real-time safe.
As such, mod-host has a limit on the amount of characters you can use on debug messages.
While testing it might be preferred to use non-debug log levels, but expect the occasional audio xrun when doing so.

Once you are done with testing we recommend to strip away all the logs if possible.

MOD specific features

The way MOD manages plugin GUIs is an obvious LV2 feature specific to MOD, but there are many others.
We will not explain modguis on this page, for that see (TODO add page) instead.
Below follows a list of MOD-specific LV2 features and examples.

Property override

A few plugin properties are possible to override for LV2 plugins on MOD, in a way that does not affect regular desktop versions.
We have this so that, for example, a parameter can have a different default value for regular/desktop use vs when on MOD. Also so that we can force a specific plugin category for MOD, as plugins can have more than one.
The properties that are supported for this overriding method are:

  • DelayPlugin
  • DistortionPlugin
  • DynamicsPlugin
  • FilterPlugin
  • GeneratorPlugin
  • MIDIPlugin
  • ModulatorPlugin
  • ReverbPlugin
  • SimulatorPlugin
  • SpatialPlugin
  • SpectralPlugin
  • UtilityPlugin
  • default
  • label
  • maximum
  • minimum
  • rangeSteps

These act exactly like their official LV2 counterparts, for which you can read their specification at
For the MOD variants simply change the URI prefix to be, for example

Extra categories



Extra plugin properties



builderVersion releaseNumber

Extra port properties

preferColouredListByDefault preferMomentaryOffByDefault preferMomentaryOnByDefault



tapTempo (deprecated)

CV Port

TODO explain here why




HMI Widgets

For tight integration of plugins and the device controls, we allow plugins to take over the device display and LEDs when one or more parameters are addressed to the device.
In simpler terms, when the user assigns a toggle-like parameter to a device footswitch, the plugin is allowed to change the the display label and LED color of that footswitch.

TODO full API explanation