OSC for Crosstalk - one manager for sending, another for receiving?
-
https://docs.hise.audio/scripting/scripting-api/globalroutingmanager/index.html
If I want to have both send and receive functionality in a plugin for crosstalk, I need two managers, one for sending and one for receiving, because the source and target ports are different and I don't what the things I send from one plugin instance to be also executed in that same plugin instance (because the callback of one manager has defined addOSCCallback)?
Am I getting this right?
-
@aaronventure No, the second manager overwrites the first.
Simply set the same source and target ports for a routing manager and filter via subdomains.
-
@aaronventure Alright, no, that still results in duplicate executions (as it executes on the instance that sends the OSC message as well).
How do I prevent the execution on the source instance, then?
I guess the real question is, how to set up crosstalk between instances when only one manager can be active, and different source and target ports are needed to prevent the source instance receiving the OSC message?
namespace OSC { // The domain takes the project name const var domain = Engine.getProjectInfo().ProjectName.replace(" ", ""); // Error logging inline function printError(message) { Console.print(error); }; //======================================================================================== // Set up the receiving routing manager const var routingManager = Engine.getGlobalRoutingManager(); // This callback triggers on message received routingManager.addOSCCallback("/reloadSamples", function(id, value) { Engine.reloadAllSamples(); }); // Set up OSC for this manager routingManager.connectToOSC( { "Domain": "/" + domain, "SourcePort": 6666, "TargetPort": 6666, }, printError); //======================================================================================== }
The usecase for my code specifically: I rolled my own flow for detecting missing samples. Once the user navigates to the samples folder, I call reloadAllSamples, and 250ms later check if the error is still in the error handler, and if not, I reset the UI.
This results in nice UX where the user doesn't have to manually reload the plugin after locating the samples.
The issue comes when they move the samples somewhere else, then open a project with multiple instances of the plugin. They can navigate to the new folder and that instance will reload, but others wont and they'll have to reload the entire project.
If I can send an OSC message to other instances to reload as well, this would be nice.
-
@aaronventure I think if you move a sample folder then you can expect to at least reload the DAW project that is using the samples. It would be annoying if you would have to open every instance and change the location there, but I think you're over engineering a solution to a problem that I would say is within normal computer workflow expectations.
-
Okay, but this is just crosstalk between multiple instances of the same plugin.
I asked about this some time ago as I was planning features and you pointed me to OS, but now it seems I can't do it properly because the source instance always executes twice.
-
@Christoph-Hart Some more findings on this today as I keep chasing crosstalk ability.
HiseSnippet 1355.3ocsW8zaaaCEmJIpXRscXEX21EBcRFMvwNMMsoAEIqNIEAst0aNsX2ZYjns4hLofDcRcGLvNrO.6i09Hrq67truAauGIksbZ5VQvp.rg46e7Ge5Geum6UnR3kkpBhWvISy4Dua42epTOpyHlPRN9.h2s8UkITMuTKjCIOYZNqrjmR77V8onIdAqQLO+0dOgkwjI7EhHjWqDI7mKFKzKj1a+mIxxNhkxOQLtl0as+wIJYGUlZB.mU8aQxYImwFxeACMaEeh2MNLUnUE80L.ODu0dhJcZ+QpKjV6esnTbZFGWzlzGBjU7QprTDwnTRmQhrzdUG6RBDkdKRBqZSBeseWQpXt7EIiuxnftvi54CuUVFdqtD7ZWGdspAuq.Rd0fzZVHcG+9IEhb8BMHdto+wRMuX.CR60gh0VxJ25F9cTfERcywry3GU.Kl6Q71sZsNE9pwtggPpuTSOmUPyXmxynOlV4HKM84nn3HfHXTFsNEbDcagWobfk7gNQiiPMUtsUKmigarA8U4oPhxseWHzinmIUmBQKaBuVjMBWJxOCjXPCpxBlMMmBgLSH4zASjIZgRRURmQnyEpr3D03bkDBy51soQ3OEF7x9cZVnlf76tLIP3JZVxkof3tPlFVGGsAx+ipbZ2vY6FVgmgbcmpnt.TMfPnc6ZGVV1o.UN9xvAyCgRfcWBLcNE1PDNPl4jQbZpZLv5nZ30VIUCBxKT+HOQSQGPqpk6sl9XZzFQz6ROTNDxBHv5Yc4X4.UbiltU30olE77LjBDQgSUTDfjfqLdcmdfYQDXfAZGVTn.NhZHrGCCCtbFOuPH0FahGaSdMBCfCU.bjKUY7lFClqCh5LWje7moGGt6y0zI4lDYAOgKNGfO08VmN19ZudNXYBAjKVjUeZl5TV12ujAwMpRPmLRTRSbuxo5BwPPcIPEotCsa+4ogAWh0ATafCLmtLm0UkciEoUTPpMqRwOlKPHeKNRyeG5PzqQidDEYCUT1fYVHZOhkE3s0G1pUq4u40C0VQs2c4bFfI5.3ktFOYySUWB6PLj.45DEXcrEbQNpyibDp0QY8gp6I7dpBMHGPgQ3IrBjsZEB3vHrGq.XpPspxnGAqwHF3RI3ZqffntBo4zBd1ZcmH16pDs0l6r0Na+fM2Yamt9mwu3HVBTlFz1FkMKz7Y150Hu1TEV4Zo7Jl0tKjUw7J.yF6RuTYLvqY0p97Bkl+RYroJS3rP5kUMXvUpyUdHCoUWgZrsYw+liwxIiOkWTuFGZHzKY4FT9e7FT06elXqzUyPk7XoP+xbt7i0Uk3JOhMybnBLUaZk8ktVY8yDo7Bh.5XE36pLRLP1MTvO+me2uuG4UGe.SypBDDSXex4EZAdD7NfeNLhgsGYf+A7xyzpbXqlWSFlZvts21ssl9RlcMzupiF4cP1vCmBYZ0OtPjpGMe5D562G4.Duuw2c2pUy68fcLO2ey60d6Me3V3gd9l5+IbVWdS+M3GkZddew6qR.6+Gu+W1i7obTto+71r1v9qdezyxaG5NK2zGK.XtxCik8Aib.C6nRmjwzKOADN1mSAv5VZrCbzBYoPOs9Xg+uMVzmJDuieOgNYzUiwUtBLBbqOGXzML4s8Obv.nz3B.tl+Q+vmmIGIy6JAMdPdvKlL1VwE1cn.cFdq2aE79occqJJReXhGyh+FdbJaiq8bJaWojLlkTndSh8VMNt5WXj.XRZlTOvuKtl1doKylmwvzyuIIY4P8ANt400w6cccbqqqi2+5531WWGev00wG9e6H9ma91IZnas4ZCgzs2glhuddGJY.CzvVI+C79wFPN
Let's take it point by point.
IN HISE:
- If I have source and target ports set to the same number, it works within the same HISE instance. The callback fires as expected.
- If I then load up another HISE instance, only the second one can trigger the first one. The first one does nothing to the second one.
- If I have different numbers for source and target ports and swap them in the second instance, it works as you would expect, like you demonstrated in your original OSC post
COMPILED PLUGIN
-
In case of the same src and tgt ports, compiled plugin will execute the callback on the first instance that "occupies" the listening port, but others can still send to it. If I delete the first instance then undo the action, the second instance now becomes the "listening" instance while the others don't receive anything
-
In case of two different plugins (changed project name between compiles) with swapped ports (8000 and 8001 vs 8001 and 8000), it works as expected, but only between two instances. If you load up another instance of either plugin 1 or plugin 2, it will not receive anything (althrough it will still send and the first instace of that plugin (1 or 2) that "occupied" the listening port will receive it.
Overall it seems really weird and unreliable doing crosstalk this way, as it also depends on firewall settings which can mess things up really quickly.
Only one instance being able to listen on a port also makes the usability questionable for plugins; perhaps maybe for plugins controlling devices or DAWs but not for plugins themselves being controlled.
-
@Christoph-Hart How crazy would it be to implement crosstalk as a timer that checks a file in AppData which all the instances write to?
My crosstalk ambitions do not go into real-time, I just need UI control and mouse-drag value setting across instances.
The OSC callback isn't synchronous anyway, correct?
-
@aaronventure said in OSC - one manager for sending, another for receiving?:
How crazy would it be to implement crosstalk as a timer that checks a file in AppData which all the instances write to?
Go for it - and report back.
-
@d-healey One problem that I'm running into is a way to identify which instances are running.
The problem is that I can't reliably know that instances will execute file writes in order (because they're separate instances), and I can't append stuff to files in HISE, I can only overwrite files. Yes, I can load, modify and overwrite, but if all other instances are doing this on load, it's a bust.
Now, how to figure out which instances are online? I can "sign in" with a unique ID into a file by writing it with a timestamp, but there's no way to know that the instance is still open, as there's no callback for plugin termination.
Imagine you wanna do a shared GUI, which displays a map of all the other instances You currently have running.
If there was a shared data crosstalk system like the one for OSC but without sending data "outside" but keeping it within a process (of a DAW, in this case) where we can have identifiers like numbers to match certain callback types etc, you'd define a callback for receiving a message to simply update the GUI, and on initialization you would send a message.
Now you load the first instance, nothing else is there, it fires into nothing.
Then you load the second one, this one fires and the first instance's callback executes and it updates the GUI, but also fires another message, this time with the ID of the instance that fired previously, so that instance only reacts to this new message so it can know that it's not alone in the universe.
This chains as new instances come online: they fire and each other instance also fires with the ID of that new instance, letting it know it exists.
I can't see a way of doing this with the file that all instances just write to. It needs a callback. I mean technically the callback is just a notification of a change taking place, but there's so much overhead with the timer object that it can't be done really fast.
-
@aaronventure said in OSC for Crosstalk - one manager for sending, another for receiving?:
The usecase for my code specifically: I rolled my own flow for detecting missing samples. Once the user navigates to the samples folder, I call reloadAllSamples, and 250ms later check if the error is still in the error handler, and if not, I reset the UI.
I did get this implemented using timers that launch on error and check for the linkfile changes, so at least that's going well!!
Also, all instances are instantly playable, no reload necessary. Smooth!
-
@aaronventure Glad you found a solution that works for your use case. The enduser would love this feature and would soon be complaining that KT doesn't have it. I think these are the kinds of VI problems that we've gotten accustomed to that really should have better behavior.
Unfortunately, I am trying to find a reliable solution for crosstalk in realtime between a client and host plugins and have been pulling my hair out (ok, there isn't that much left to begin with) over these same OSC behaviors. I've about given up on it, but FWIW @Christoph-Hart I would also request looking into the mentioned behaviors, because they're very unexpected.
-