DISTRHO / Cardinal

Virtual modular synthesizer plugin
https://cardinal.kx.studio/
GNU General Public License v3.0
2.22k stars 153 forks source link

Improve OSC implementation #564

Open riban-bw opened 1 year ago

riban-bw commented 1 year ago

It would be advantageous to improve the OSC implementation to allow full manipulation of the rack, e.g. add/remove modules/cables, etc.

riban-bw commented 1 year ago

I am working on a patch to provide enhanced OSC support and will submit a PR when complete. The forked branch is here. I am adding methods for fuller manipulation and monitoring of the rack and updating the associated OSC documentation.

riban-bw commented 1 year ago

Progress

Implemented: /load s:filename /get_modules /get_module_info h:moduleId /add_module s:plugin s:model /add_module s:plugin s:model i:xPos i:yPos (I haven't tested this) /remove_module h:moduleId /get_cables /get_input_cables h:moduleId i:input /get_output_cables h:moduleId i:output /add_cable h:srcModuleId i:output h:dstModuleId i:input s:color(optional) /remove_cable h:cableId /remove_cable h:srcModule i:output h:dstModule i:input /param h:moduleId i:param (requests parameter value)

Response are sent to requester on path /resp/context, e.g. /resp/module

Issues

falkTX commented 1 year ago

I would advise you to do this in small bits, one PR for each related change. Loading a filename is something I will NOT add, because this requires knowing which files are available too which then requires full remote file system access. We need to take into consideration that OSC is meant for remote communication, running it locally should be done for testing but we cannot rely on local file paths or resources

Is there even a point to add all of this stuff regarding adding modules, making connections, etc etc? Who is even going to use this?

The current methods available on Cardinal have all been tested to work and are known to be useful.

PS: regarding modules crashing due to width stuff, it is likely that is this due to modules not being created properly. Rack assumes (even in headless mode) that modules are placed within bounds and with proper positioning, it is how module extensions work, we need to be very careful when creating new modules or messing with the internal patch

riban-bw commented 1 year ago

The main purpose of these OSC enhancments it to allow complete control of a headless device including requesting its current state and manipulating modules (add / remove / params) and cables (add / remove). I could not find how to do so without OSC and the current OSC implementation is lacking these features.

Regarding loading by filename - this is much easier for a remote device to send the filename than to create a whole patch, compress it in the right format and then pack it as a blob. I anticipate a remote control device being able to request available files, e.g. in a documents folder and to load and save patches by filename.

Regarding baby steps - yes, let's get something working but to provide any tangible benefit I had to implement all the model manipulation methods and prove they work, i.e. it is of little benefit to be able to add a cable without being able to remove it or know what modules are available to connect to.

falkTX commented 1 year ago

The main purpose of these OSC enhancments it to allow complete control of a headless device including requesting its current state and manipulating modules (add / remove / params) and cables (add / remove). I could not find how to do so without OSC and the current OSC implementation is lacking these features.

This bidirectional communication is impossible to achieve properly due to how Rack was designed/created. There are many modules with an internal randomize property, and Rack itself also provides ways to achieve the same. We then also have modules with hidden state that is not exposed as a parameter or port, for which we simply cannot hook into in order to keep things in sync.

That is why for current Cardinal the communication is only one way, and by sending the whole patch content.

What you are trying to do is impossible (in a proper way) using the current Rack codebase, as it was not made with this in mind. The only alternative I found is to severely limit the modules in a new "mini" variant, using only those that are hopefully good for such remote setups, anything else just doesn't work.

What the current Cardinal does when you enable "auto-push to remote" is to send messages for things it knows are safe to do so (currently only simple knob value changes) and everything else will send the entire patch. If you want something more deep than this please fork Cardinal and handpick + fork modules to support the more integrated approach.

riban-bw commented 1 year ago

Maybe I will have to live with the limitations you mention until such time that I (or someone) enhances rack functionality. For simple stuff like creating a basic set of modules and interlinking then adjusting parameters this should work. I now have a mostly working OSC implementation so will be able to test how useful it is within the constraints you describe. I will update here.