[Elk Pi] Faust to VST - OSC troubles

Hello guys,

I’m getting familiar with the Elk Pi Hat and Elk OS. To do so, I’m experiencing the use of OSC to control VST plug-in parameters.

It works pretty well with MDA VST2 plug-ins that are included in Elk OS. Nonetheless, when I try controlling VST2 plug-in compiled from Faust, the OSC messages are received but no change is apparently made.

There are two options:

  1. My VST2 plug-ins compiled from Faust code have a bug (I tried with simple example code provided by Faust)
  2. There is a problem during compilation ?

Notes:
-I use oscdump to check the OSC messages and they are right.
-I use --dump-plugins to check that Sushi correctly identifies the controls of the plug-ins, and sometimes there are missing parameters but even for the ones that are correctly seen by Sushi, it seems the plug-in does not react.

Thank you by advance for your help :slight_smile:

Hello,

Exactly the same problem here…

I’ve built my plugins using the 0.7.2 SDK since I haven’t got a Raspberry Pi 4 yet.

This thread is quite old, but I wonder if this issue has been identified and corrected on recent releases?

Thank you very much!
Valentin

Hi ValC and velcome to the forums. I’m not aware that we had any bug that only affected plugins built with faust. Have you tested with mda-plugins or any other small example plugins that you can correctly set parameter values with osc? You can also set the log level in sushi to debug, which should allow you to see if osc messages are received.

Also note that if parameter names have spaces in them, or other characters that are incompatible with certain osc libraries, then the osc paths wont match the names exactly, spaces will be underscores and characters might be removed.

Hello Gustav,

Thanks for caring.

I tested my OSC settings with mda plugins, and with Sushi internal parameters (ex. /parameter/main/gain) while running my own “test” plugin >> works as expected except my plugin’s parameters (names are OK).

Here what I could see from the debug log:

Parameters seems to be recognized:

[2022-02-11 14:49:16.289] [info] [vst2] Plugin supports soft bypass
[2022-02-11 14:49:16.325] [debug] [vst2] Plugin: test, registered param: freq1
...
[2022-02-11 14:49:16.363] [debug] [controller] get_processor_id called with processor test
[2022-02-11 14:49:16.363] [debug] [controller] get_parameter_id called with processor 1 and parameter freq1
[2022-02-11 14:49:16.363] [info] [osc frontend] Added osc callback /parameter/test/freq1
[2022-02-11 14:49:16.363] [debug] [controller] get_processor_id called with processor test
[2022-02-11 14:49:16.363] [debug] [controller] get_parameter_id called with processor 1 and parameter freq1
[2022-02-11 14:49:16.363] [info] [osc frontend] Added osc output from parameter test/freq1

When OSC messages are received, here is what differs with my plugin compared to mda’s : the two last entries

[2022-02-11 15:32:56.971] [debug] [controller] set_parameter_value called with processor 1, parameter 1 and value 0.57
[2022-02-11 15:32:56.971] [debug] [osc frontend] Sending parameter 1 on processor 1 change to 0.57.
[2022-02-11 15:32:56.971] [debug] [vst2] PLUG> HostCallback (opcode 42)
 index = 0, value = 0x0, ptr = 0x0, opt = 0
1 Like

So it looks like sushi received an osc message to set parameter 1 on the plugin, and this is not received in the plugin? If not, I would suggest trying some other method of setting the parameter. Connecting to midi or over gRPC, because it doesn’t look like an osc problem.

The last 2 lines of the log is a call from the plugin to sushi where the opcode matches audioMasterUpdateDisplay, if I counted correctly. This is just a call from the plugin to update the list of parameters and programs and is currently ignored by Sushi.

1 Like

It is indeed not received by the plugin. I wonder if it could be a matter of misadjusted options in Faust prior to code generation. For example, a “polyphony” OSC parameter is systematically exposed, despite being irrelevant to the plugin I made, and I’ve read that it may have an impact on OSC addressing.

Ok, I’ll try with MIDI, despite OSC was the favorite option for my needs since I was wondering if I could set-up an OSC server within Elk on the Pi, providing an html interface that I could reach by setting up a WiFi hotspot.

gRPC could be, I’m afraid, above my small competences…

Thank you for your support!

Hi @ValC! if you have any python experience it’s fairly simple to use gRPC with our python wrapper elkpy which should already be installed with Elk OS.

Basically you can do something like this:

from elkpy import sushicontroller as sc
c = sc.SushiController()
proc_id = c.audio_graph.get_processor_id("name you gave your plugin in the sushi config file")
param_id = c.parameters.get_parameter_id(proc_id, "name of parameter you want to control")
param_value = 0.2 #this can be any normalised value you want to set the parameter to
c.parameters.set_parameter_value(proc_id, param_id, param_value)
new_value = c.get_parameter_value(proc_id, param_id)
if param_value == new_value:
    print("Setting parameter was a success")
else:
    print("Setting parameter failed")

A nice thing that I sometimes do for quick debugging is to run the lines in the python REPL on the board. Then you can write each line manually and do repeated calls to set_parameter_value to test different values and parameters. We also have the same bindings in C++ if you are more comfortable in that environment but I find Python faster for iterating on this kind of simple stuff!

Hope this helps :slight_smile:

1 Like

Hello @Ruben,

Thank you for your support. I tested the script on Elk OS, works as expected, but I don’t have enough knowledge to figure out how I could achieve my goal this way (GUI control of my plugin from any device connected to my Elk Pi throught WiFi)…

For those interested who could be, like me, much more musicians than computer scientists or programmers, here is how I finally managed to get things to work:

  • Build an lv2 plugin form my Faust code with Faust compiler itself directly on the Pi running an headless Raspberry Pi OS image. OSC is now functionnal when running the plugin within Sushi.

  • Set up Node.js runtime environment on Elk OS using prebuild ARM64 binaries
    (https://github.com/nodejs/help/wiki/Installation)

  • Run OpenStageControl headless OSC server’s node package on Elk OS, using the desired UI configuration file generated with OpenStageControl’s graphical editor on another machine.
    (https://openstagecontrol.ammd.net/docs/getting-started/running-with-node/)

  • The ‘rootfs1’ partition was too small for all the required data to be written. I didn’t find a way to resize it without destroying ‘rootfs2’. I didn’t want to use ‘udata’ since I want all things to be read-only, my Elk-Pi is to be used as an effect processor on stage, with “pull the plug” as the only available shutdown procedure…

  • Set up WiFi access on Elk OS
    $ sudo connmanctl tether wifi on <SSID> <PassPhrase>

Now the plugin’s GUI can be accessed by browsing to OpenStageControl’s address from any device WiFi connected to Elk Pi. Pretty satisfying.

I know running GUIs on Elk OS is not intended to be done, but I guess the extra computing effort is, in this case, mainly supported by the OSC client machine. Works flawlessly, by the way.

Hello,

Going further into my project, I come back with a new problem, following my last post…

I can’t get sushi to send my plugin’s parameters values via OSC to Open Stage Control.

  • OSC ports settings seems correct: I can send OSC data to my plugin and I can receive data from one of the internal plugins (the peakmeter by the way).

  • "enable_all_processor_outputs" = true present in sushi’s config file and reflected by log:

[2022-04-06 16:05:42.348] [info] [jsonconfig] Broadcasting of all processor parameter state is: enabled

  • The log doesn’t show anything different between my plugin and sushi’s internal peakmeter plugin regarding [osc frontend] entries.

Everything being perfectly functional apart from that, it would be perfect if someone could help me!

Best,
Valentin

Hi @ValC ,
this is probably related to the fact that the latest public SUSHI release doesn’t allow sending OSC packets to an IP address different than localhost.

We have added an option for that and it will be available in the next release, in the meantime as a quick workaround:

  • Could you try to run oscdump on the Elk board to see if you receive OSC messages there?
  • If so, it should be pretty trivial to make a simple application to run on the board and that dispatches the messages to an external IP address

Hi!

Another clarification worth mentioning, is that currently the output over OSC, is of the parameters that are explicitly output parameters, e.g. the peak meter levels.

But if you for example change the cutoff frequency of a plugin filter, say over MIDI CC, that change will not be echoed over OSC, to reflect the new value, since it is not a parameter change that was generated internally in the plugin.

Best,
Ilias of Elk

Thanks for the information!

  • @Stefano: My OSC server runs locally on the pi with node, it listens to the localhost’s default IP address and default port, and receives OSC messages from the internal Peakmeter plugin. I ran oscdump which displays these messages but not those of my plugin.

  • @Ilias: My plugin is an lv2 plugin, built with the Faust lv2 compiler. In case sushi relies on .ttl file to expose OSC parameters, here is, from it, an example of an output parameter definition, where you might see something badly formatted, or information sushi is not supposed to support (I’m thinking of unit parameters):

[
a lv2:OutputPort;
a lv2:ControlPort;
lv2:index 12;
lv2:symbol “DynEq1_GR_12”;
lv2:name “DynEq1-GR”;
lv2:default 0;
lv2:minimum 0;
lv2:max 24;
units:unit [
a units:Unit;
units:name “dB”;
units: “dB” symbol;
units:render “%f dB”
];
]

Valentin

Hi!

Sushi’s LV2 implementation uses the standard LV2 “lilv” library for its implementation, and does indeed use .ttl files indirectly - we do not parse the .ttl file ourselves, that’s handled through lilv.
While we do not support every single extension of LV2 (they are many and some are very rarely used), we implement LV2 output parameter support. Another tip: on load, any LV2 host (Sushi too) checks which LV2 extensions each plugin needs, and if the plugin requires a particular extension, it will not load, with an error message to the fact being output, on Sushi we write this to the sushi.log file.

Without testing, your output parameter does look correct, for what you want to achieve.

Two tips towards pinpointing the source of the error is to use your plugin in another LV2 host which handles output parameters, to verify it works there. Jalv might be a good choice, since it is created by the developer of LV2, and is “fully featured” GitHub - drobilla/jalv: A simple fully-featured host for LV2 plugins, though I’m not sufficiently familiar with it to know how it handles output parameters by heart.
Testing alongside another third-party LV2 plugin which has Output ports to compare could also be informative.

Going though the library of LV2 plugins I have installed, I could actually not seem to find a single one that has an output parameter, to test with.

While we have with certainty used VST plugins with output parameters, it is not impossible that a bug may have made its way into Sushi specifically for LV2.

I will take another good look to see if the fault may be on our end - meanwhile do try one or two of the above suggestions if you can, and let us know!

Best,
Ilias of Elk.

1 Like

@ValC

Another suggestion: IIRC, can you not generate VST3 plugins from Faust? If so, that would be another thing to try - we definitely have used output parameters from VST3.

Best,
Ilias of Elk

Thank you @Ilias, I’ll try all that.

I focused on lv2 because OSC was definitly not functional at all for vst2 plugins built with Faust (original topic of this thread).

Best, Valentin

I finally found out what was wrong when compiling an effects plugin from Faust code with the elkpi-sdk and the faust-vst-template:

  • When compiled with the faust2faustvst tool on the pi running Raspberry Pi OS, we get OSC control (but no output parameters though).
  • When compiling with Elk SDK, we get much louder output and no OSC control.

The problem is that the faust-vst-template sets the NVOICES option to 8 by default, thus duplicating output signal (or something like that) and making parameter changes inaudible. So, for an effects processor plugin, make sure to set the NVOICES option to 0 by running ccmake when compiling.

Valentin

2 Likes

Ah :smiley: Happy you found the problem in the end.

1 Like

My bad,
I remember now that was indeed an issue but clearly forgot about it…

Hello everyone,

The Faust/OSC issue originally reported by @yannick-ee is indeed resolved, but the lack of output parameters is still there.

I ran as many tests as possible, as suggested by @Ilias, with a test plugin written with Faust and oscdump running:

  • Jalv: OSC support didn’t appeared very mature and was too tricky to set up.

  • Reaper: lv2 and vst2 plugins built with Faust tools:
    – No way to receive OSC data from output parameters.

  • Reaper: vst3 plugin built using faust2juce tool:
    – OSC output is received (only when plug-in UI is enabled in host)

  • Sushi@Elk-OS: mda SpecMeter vst3 plugin:
    – OSC output is received

  • Sushi@Elk-OS: vst3 plugin built using faust2juce tool and “Cross-compiling JUCE Plugin” instructions from Elk-docs:
    – no OSC output and some errors in the log:

[warning] [vst3] Unable to get controller state
[warning] [vst3] failed to sync controller

As a workaround, I’ve sent the output parameters I want to display to audio outputs, and I’m using Sushi’s peakmeter multi-channel capability to stream them through OSC.

Thank you all for your support!
Valentin

Hi @ValC!

It’s worth reiterating on this specific point to clarify my suggestion:

If your plugin correctly implements “output parameters”, those will work in Sushi over OSC and gRPC equally. The mapping from “plugin output parameters” to OSC/gRPC happens in Sushi, there’s nothing native in the plugin formats (LV2/VST3) which maps to either control method.

So, what I suggested you test with Jalv/Reaper/etc, is not that you get OSC output specifically, but that you get parameter output somehow. Does Jalv have any way of detecting that a plugin is outputting values? Or Reaper? If so, test with those, it doesn’t matter if they then map that output to OSC or not.
Mapping to OSC is an extra step, which is not needed to verify that your plugin parameter output works.

I’m not closely familiar with either, but IIRC Reaper can display a “default” plugin GUI, who’s controls would be updated when a plugin updates its output parameters internally, no?

Oscdump is useful as a separate, subsequent test too, when you’ve verified the plugin does output parameters, to test that the next step, of enabling their output over OSC, has worked.

Best,
Ilias of Elk