Sushi lacks any such mapping features internally as far as I know. While hosted plugin parameter changes are communicated from Sushi, that is over OSC and gRPC only.
So, what you are asking for is easily implemented in an external accompanying “backend” / “controller” application that you write and run alongside the Sushi instance, on e.g. your device.
In this specific case, you would enable OSC output for the desired parameters, listen for OSC in e.g. your Python program, and on change, map and output the value to the corresponding MIDI CC, which your Python program should be made to output.
You could also use gRPC instead of OSC if you prefer, but for the specific use-case gRPC might be overkill, and OSC will do nicely.
Just to add to my answer yesterday - I’m not sure implementing this in a plugin will in the end be saving you all that much effort:
Depending on the plugin format, you may need to do a lot of extra work, to ensure that you do not allocate any memory/cause interruptions in your plugins audio processing callback, when handling incoming gPRC/OSC, and outputting it as midi.
But if it runs as a separate process, you do not need to worry about any such overhead, meaning your implementation is likely much more straight-forward.
Hi laenzi, to add to Ilias’s answer above. Unfortunately not without doing some modifications to sushi if you want output the peak values as CC messages.
You can output midi from a plugin (only VST2 as VST3 doesn’t do midi) and route midi from a plugin to a midi output, but only keyboard messages (note on/off, pressure, modwheel, etc) will be passed through. Reason for this is that sushi will first convert the midi messages to a internal format, and discard things like CC messages.
Thanks Gustav, thats good to know. I dont need to send CC messages, I could also use other messages. I was not aware the VST3 does not do midi
Ideally i would like to use CLAP, but since Sushi does not support it, I would then rather fallback to LV2.
Would that work out (based on your experience)?
For simplicity reason (and also from my personal lerning interest point of view) I would rather try to implement a plugin, than having an external service running. It looks a bit cleaner and more reliable to me. The plugin would then also do the measurment algorithm which I would like to tune (eg. the frequency of sent messages…)
@Gustav I have built a debug version of sushi (tag 1.0-rc1_yocto_build since the README of sushi mentiones this as the last version compatible with Elk Audio OS.
Then I used gdb to trace the code related to to the MIDI processing from LV2 plugins.
That exposed the follwoing issues:
a) when converting the midi message from LV2 the last byte is ignored due to this line which decrements the size of the MIDI payload. It might be that this is required for other types of messages, but for Note OFF message this causes the loss of the velocity information.
b) In the internal format KeyboardEvent the range of the velocity field is expected to be 0.0…1.0. However the values are 0…127 as written by the lv2_wrapper and therfore with the encoding on the midi_dispatchter.cpp the velocity value overflows the 7 bit range of the Midi Note OFF message.
As a next step I can propose a fix in a PR.
One thing that is still not so clear: Why is the MIDI channel of the incoming message ignored and instead the channel of the Output Connection is used? What is the rationale behind this?
Hi Laenzi, this goes back to the early days of sushi
Originally internal note on/off messages in sushi did not have channel information. The idea was that you would use channel information to filter midi messages to different tracks, but once note data was received on a track, it was assumed that channel information was redundant.
Often you would also set a track to omni, where it would receive midi from all channels and essentially not care about the channel info. Though there is no corresponding concept for omni for outgoing midi, outgoing midi messages need to have a channel assigned to them, hence why the channel is assigned by the routing layer and not by the processor itself.
Eventually we added channel information to the internal note messages, meaning that it would be possible to use the channel info coming from the processor. We didn’t change the outgoing behaviour for compatibility reasons though.