In this article I’m going to show how you can compile a Faust program to run on Mod Duo. Faust is a programming language designed for real-time digital signal processing and Mod Duo is a multi-effects guitar pedal that’s built as an Lv2 host(you can think of Lv2 as an open source variant of VST). Mod Duo is a pretty outstanding obelisk in the world of music hardware: you are not limited by the manufacturer what kinds of effects you can put on it, it runs Linux, and you can even freaking ssh into it. What else do you want?
In this article we are going to build our effect pedal from scratch in Faust, compile it to Lv2 plugin, and generate a user interface for it using MOD SDK. Finally we are going to deploy it to MOD DUO.
Faust already comes with a script to compile to Lv2 target, unfortunately we can’t use it, because it wouldn’t work inside mod-plugin-builder custom tool chain. The script is called faust2lv2 and using it is very simple:
This will produce a folder am_modulator.lv2, with everything in it ready for a generic Lv2 host to run it.
We can use the script to discover what we need to do in order to produce an Lv2 plugin. The script is rather complex, so instead of studying it’s source code we can just add(or uncomment) this line at the top:
Which will cause bash to output all the commands it’s executing. I have already done this and discovered a build sequence that works, so you don’t need to do this, but it may be helpful source of inspiration if you are trying to adapt your build to some unusual environment.
TLDR(Too Long Didn’t Run)
The purpose of this article is to explain the build process as much as possible. If you are in a hurry, I have wrapped up all that I’m doing here into a helper script. You can find it here:
Running it is as simple as:
You can then proceed to MOD SDK.
Write A Faust Program
Create a directory in your mod-plugin-builder for your plugin’s source code:
Change to the plugin source directory if not already there and create the plugin file with the following source code, or use your own example:
Honestly the pedal effect we are going to build sounds pretty awful. It’s a great pedal if you want to make every string sound out of tune. If you have a more exciting example don’t hesitate to try it, I’m just new to Faust and don’t know what I’m doing yet. I got the example from an online course and just modified it slightly to work with audio input:
https://www.kadenze.com/courses/real-time-audio-signal-processing-in-faust/info
Creating a Makefile
Create a Makefile in am_modulator/source by running following command:
Compiling Faust to a Library
Let’s go over the build rules here before moving on. The first rule in the file produces a C++ file from Faust source code:
There a few things to note here:
- Output file is specified with “-o”. Apparently Faust compiler looks at file extension to determine what language to compile to.
- The “-a” option is the architecture file, this is what’s telling faust compiler that it is targeting Lv2.
- The “-i” option asks to “inline architecture files”, this basically means it will paste things like referenced headers directly into generated .cpp file. This would help make compilation more straightforward later.
- The “-cn” option stands for “class name”, this indeed will become our class name, so it must be a valid C++ identifier(you can’t have dashes for example, among other $#*!). Peeking inside generated am_modulator.cpp we can confirm that the name is used as the class name:
The next important rule in the file is the one that compiles “.cpp” file produced in the previous step into “.so” library:
Create am_modulator.mk file
You may have noticed that the build rule for “.so” file calls C++ compiler indirectly through $(CXX) definition. This is definition will be provided by the ./build script. This is necessary because we have to cross-compile for Mod Duo’s ARM architecture, and we can’t just use our garden variety g++ command. Instead we are going to let the ./build script in mod-plugin-builder inject it’s own C++ compiler. For this to happen we are going to need to follow a few conventions:
- Plugin folder must be located in ./plugins/package/
- Plugin folder must contain <plugin folder name>.mk file
- File <plugin folder name>.mk file defines variables describing source code location, version, dependencies, as well as commands to configure, build and install the plugin.
- All definitions in<plugin folder name>.mk file must be prefixed with “<plugin folder name>_”, where any “-”(dashes) are substituted with “_”(underscores).
Create the am_modulator.mk file in ./plugins/package/am_modulator/ folder:
There’s nothing here that’s specific to our plugin, except the name of the plugin “AM_MODULATOR”, which we substitute into the template using sed command. The only thing we need to understand is that when we use the ./build script, it will call make command for us from AM_MODULATOR_BUILD_CMDS procedure, so we don’t have to call make ourselves.
Manifest Files
Our last two build rules generate “.ttl” manifest files:
The first rule creates manifest.ttl from a template. It needs the template file manifest.ttl.in. Create it now by running the commands:
The next rule doesn’t need any additional files, it compiles am_modulator.cpp to an executable(instead of a library) and then runs it to generate plugin specific am_modulator.ttl file. This will contain audio inputs and outputs and the controls. There’s nothing here that you need to edit, you already defined it within your Faust program.
Building Lv2 Plugin
We can now build the plugin:
If all goes well, you should now have your plugin built in ~/mod-workdir/modduo/target/usr/local/lib/lv2/am_modulator.lv2.
Creating MODGUI using MOD SDK(Ubuntu)
MOD SDK is a web app that allows you to define basic look of your plugin. While it’s “recommended” to run it in docker, I found it suffers numerous issues when it is running inside a docker container(screenshot issues, deployments not working). I’m going to show how to run it in Ubuntu, hopefully it will give you a hint how to get it working on your distribution.
Clone MOD SDK by running:
Install the dependencies:
I had to downgrade to older version of tornado(see https://github.com/moddevices/mod-sdk/issues/11).
Set the path to your Lv2 output directory and run MOD SDK:
If you navigate your browser to http://127.0.0.1:9000 you should be greeted with something that looks like this:
Make sure under Information it reads at least your plugin name correctly, if it doesn’t you might be having an issue within manifest. If all seems well, go an head on to Icon tab, and configure your plugin’s skin. Here’s what I got:
Once you are done with that, you need to generate the icon screenshot. Go to Icon Screenshot tab and generate images. You may need to refresh your page to see results(Ctrl + F5 for full refresh). Watch the logs(stdout) of MOD SDK for errors — the screenshot portion of the MOD SDK is known to be unstable.
Finally, plug in you Mod Duo, go to Deploy tab, click on device. You should see address http://192.168.51.1 show up or just type it. Click Deploy via webserver. You are done.
Here’s what it looks like in Mod Duo:
Conclusion
I have shown you the steps required to build Mod Duo plugin in Faust. You can use that to create your own build workflow, or you can use my script modduo-create, which will automatically generate a Faust template with a Makefile and supporting files. I hope this will encourage more people to experiment with Mod Duo and eventually I would like to see it turn into a kind of Arduino of guitar world. You have no excuse to not experiment, dust of that compiler and write some code!