Making plugins that network with each other
-
I can't remember if I asked about this before, but -
There are some examples of plugins that network with each other somehow out there. For example, Virtual Sound Stage 2 is able to display the stage position of every other instance of the plugin, as well as synchronize certain settings, such as which hall has been chosen. I think VSL's MIR does this too.
How does that work? Does it use LAN networking? Does HISE have any similar capability, and how would I approach doing that? -
@Trivalve Might be possible using a JSON file that is shared between the instances. You'd need to poll it with a timer or deferred note callback I think, depending on exactly what data you need to share.
-
@d-healey That's an interesting idea. The file would need to be re-written and re-loaded any time the project in the DAW is loaded, or it would somehow need to be able to be saved with each project.
Example data would be things such as stage positioning, early reflection strength, which stage every player is being set in - that data would need to be polled with a timer, I think. I worry that using a timer would affect performance when doing absolutely nothing. I wonder if there's a way to only poll while the VST's GUI is open... but then again, that wouldn't work for shared data that isn't purely visible. It seems like implementation of that could get incredibly messy. That's also just examples from VSS2, which is one of the few plugins I'm aware of that communicates with its other instances.
I'm pretty sure VSL's software uses some kind of LAN network. I know VSL's sample players share loaded samples with each other - if you load the same patch on two different instances, the sample pool is actually only loaded once. It's hard to actually tell how that all works, and the answer is probably proprietary, which is frustrating.
-
@Trivalve Here's a good start:
Notice that the JSON is overwritten at the next launch. If you want to have different configurations, you'll need to save the object in a panel that is recalled with presets, and re-write the file from this object at init.
@Christoph-Hart Is it good practice to check a JSON file in the system every 100ms?HiseSnippet 1226.3ocwW01aaaCDlJIZaVadXEXaelyeRFvy0NIqaXECy0NIEdaIwqtKX.EEEzRTVLQhzSjJIFAAn+z5Oo8OX6nnjkRhSPhABprArIuW3CetiGOMJQ3QkRQBxp1qmOihr9B6wy4pvAgDFGMbGj02ZOjKUDNn2NDEYbHIgwmh5OeFQJo9HKq0eoVWqZafxd92esOIRqe4THzQBlG8OXwLU4ri586rnn8H9zWyhqn818F5I3CDQhT.Wqa2AMi3cBYJ8.hVs0rQVext9LkHYrhnnRj0F8E9yGGJNiaz+HljMIhpGzEMFbjY58DQ9ZDqmEMHjE4OpX+KQfWFUxFqaXiu1delOaw7krxWkI.WZQU9vZs6BdcqBuN2e3YUAdaXf2SrG6kvloJknw1mCQLEMIf.gfpvxnKZsuw1df.zfqZGSNgtWBLXgEtOqSmV3M6zo4yq6.pIEQz1dQTRhqdF8GH3HU3SIIXED2RFwiv+BtviDe+QDNMxsQgvFs5zJyaESzVBTgV+DQja.IRRuommn3RvquovsSopAh3YBNLvsQ+TkRv61nYq5N3a7bW1r4JXyVqfMa2n4ay2TLdDiSwAobOESvwBdeXyUr+8JrrEruiRoMq6bgYwXAXWyTWTt5k+qjMUhY5CPl.zMU7oOE6kPgLQrJjhESNtTTNSOz+bfqunAy+7F+rl4ay39zyOLnDcMuL22kFuKeJruZ6mFO6Exea7gG3ZbUKbCenPQ6ikMVNfpfbRhx.8tlDNs3Kq6nWr.QB1cBlwyxEZhmzVp44LVa.IJZBTSv8JbYQVT0LMpw+KLnHJ31z4BmZ58uFquhR7AFHeGEIH9vgh3r8zU1K0fu.cNLHiJAbog2+jRkYAVlDKBB.UzQN72kg62T391.49VcpxQ5PpaScPslgWpkGkdEEfKFPpI6W.qQxYLIcwhMnO9LnhIVbJHHgkGQOVJ3kNYBEHNJ9LJNjbJESvdg5ZwXk.q8t1foBgOjERyMZoDsAkYwjpnbIaoEJ2s4ycpcoykvO2QDtxwfCDJ5g4QBmKcvWWTPvRkkGsizI7KQb9Qga2PWdZ7DZRw4sBEghpWsps8sW0t5kJdlp.UTTvGxYpCmQ42VsbTdoC8kN4nBTUkUS+KyqoapifXPo6Z14E7PYPFflU1EkO.S2rvzxaoeHlu00M+gs5auDy+qg51Iz2qkSF.AMilnXZt2ZG5oPCCla4pYuCUdBTkC13KJzhr9z6Aec9hk78i6MewfO7m8Ni4qBWLQui5ERYSCK6N4860Kg3yDuLQjN6Zz1C.BaVABH1GEHrUEHfUeTfv1UfvGt3Q.B1FHTuneHcGHYHvwtnVjFBlyMyK9yoEmnsVGcylqfV7D9oQD0U66S2rat.nrxUZvR2DEWxTyqByGklAuuv8I1iXJuvki20VBdgyiO13Mu05516FDP8TkfcC6896G+9nQuRjpf2fYehJgoyINHMdL7lFdT.IbHuQW52ZMcANy3NEoKiob+rA+G7jKrqdrUtvtEBQwDuDw67LUH0Mu+YYy.Xhm8NL0r2WOFWVQ2tS6NnX3cJdmmmlJ9d.6K2lMWAa1ZErY6UvleXEr4YqfM+3JXyOcm1nectWjpDwliIvDi1M6BJKqc4DHKKKiD8+3NDOvC
-
I can see a problem though. It will be the same file used for every DAW session.
-
@d-healey Hey, who else can boast a plugin that can communicate between DAWs?
More seriously, there might be a way to create a unique property per preset and push it in the object.{"preset1_idx" : "", "preset2_idx": "", "preset3_idx": ""...}
I thought about using the preset name but it's edgy (preset name change in the future, use of -init preset before first save, etc...)
So secondly I thought a random propertyName that is saved in a panel. But then the JSON can be filled with hundreds of useless old junk after years using the plugin, and I don't know how to flush it...
-
I can't think a way of fixing up this issue, although is it really a big deal? I mean, how many people use more than 1 DAW at the same time?
-
@ustk But they may switch projects.
-
@ustk Got it! You can allow the user to choose between groups of communication... I'm on it...
-
@d-healey said in Making plugins that network with each other:
@ustk But they may switch projects.
that's where the grouping thing can be helpfull...
-
Here we go:
(still not saved in preset though)HiseSnippet 1411.3ocwXE0aaaCDlJIJK1ctXEXXOy4mjAxbscx51ZvvbiSRg2ZSLp6BJPPPAsDkMajI8jnShWP.1Os8394r8KX6NJIK4FGiDuVTYCXQx66tu6NRdjtSnxkGEoBIVEd8jQbh0ma2chTOn0.lPRZuGw5qraKizLIH2dLMq6.VnP1mr6jQrnHtGwxZ0mixZUXMh44u+ocYAn7YcQHGqDt7WHFJzY81o4uHBBNf4wesXXNo2tYaWkrkJPMF30p10HiXtmw5yOjghshMwZ888DZUXWMSyiHVqsqxaR2ApKjwxerHRzKfiMpS5BJJt6CTAdHiwdIsFHB75j5+QDPKcxhFqFGM9R6WJ7DS6OKp7ElAnYHxGOrVYQzqdd5U6tSOqbzasX58H6ttghQ5rQPt8.Hio4g9LHEjmVwxRV4uV2tkBjPpqNjcF+fPnwTDNOoVsMoMpUqxNkJBhEoB3UcC3rPGrG7CjbhzzyYgTMj2B6HCn+HMUiLOuNLIOvob5fk2r1lFsk1Q0HHTfxGpBb7YAQ7ap4dZYDn0SRUaettkZ3HkDZ3Td2wZsRVubkMKUjdimEgowRfYqk.y1kqb5Ny5RRt94gpwi1cgtVeTj5fL2hQWrwMnaXPeZRLEMsoazlXmIg21dWB8bUYg2kke5Imdch3BYfPxo9iktZgRRUx9IjNMi4lZtMA2JXLuRohWUpXAgO0ItM1BoXpUy63UERO9kG4mokJ6Trv0kJh12WERc5QExYfTg1qZD5kFy2hEDzC1Nv4FDCmDkDbhck44LnBWrif3mwWnSUZ5aYSj0pQ3dWwqMtofXnVXhy8tEeednxdKNMUETwIFm8z6ol1W1G7+pdiGN5YQ+b2iNzIViaRK6A6kW8cQkmOvbdHKTG6h0i2S.G9F4qdKJOkKlmtPG+jYCdrElBIMe4To3UEKfAQjsuhy7.+OwmBTLOXmqgFuZFuo.78wOl11mpGvQlgD72FyiLSADQTkuex7U5WaX9IopOWj9Tbk0w3b.mJSmQm7Cn8WwAVSABGuSkBLU3EhH9Ta1ZW5EP0Mp5bXfPgNdj2EojYJoGGhfb5Eb5.14bJi5N.qaR0JJpcDPekxCl1xS.M2HdLKMIm7r718roXpaV7U7Z3mEjwys74PkleTRdo30Eou+P99ycrjre.tPYNCmrD51A5HGOrGOLccZpfPcvYKzZe6EZyeN.238NyInR1VJzGMhKusxujjMbgBwqmvJPTsoL7CSJCGu0OQ3g0fmtQNwP57mOhb2UPibJv1xf+N.tfcRExo1dcqzShcOf2HCNYIfu0+O3aOG3+Za7Ln3ggRRGPJZDOTKvru0d7ygSYFeznB16wiNC1elXswzBjPLL1rkRO3DdTEiUKZmtBfbYZndR5KmmNOxZURNk8YyprWv5knrMrMuWOVU9op5AvKZ9kZ73iGx0WnBOiZJy8ThO3NcE+dtoI0Zxg41r4X1MtSy5Ll1wJwzODz3EBO8foF3ONn4.tn+fbGH+GZFx7DJCkv0AMRXK918h.MlRf+g7gg.0IyIvuvY9WlYntMmjYiiaNKMZd76SCfX4owLqauGTnQNJPDeRnvV4n.U+IgBamiB+4UennvMuJDbgLk23.ld1aogWMMY.nhxLWGBuxiLRnmjWyeTt51cktOxtiP6NX97ck4vWXivO17M4hvkr222m6pyH6Z1G7lO925k7J0XsP1+kLcn.2Q4vwC6pFG5xAlHgMuwp9VqfUVhaWKcO6tbomow+BOICVGaakLX8zAICYtgp25FWZBup8Fld.NIM+iCEreI1lNsbpscsp0HCEdh255hghuA397wzXIvr0RfY6k.y2tDXdxRf46VBLe+Bwf+4KOarVMLdYBzQm8MmLvxZeIVyzLij7eoeKByC
-
@ustk oh thats quite cool...
-
Well, that was an educational attempt at the usage of json files. But I can't help but wonder if there's a cleaner, more 'proper' way to do this. One less prone to bugs rising up from working on multiple projects.
Maybe @Christoph-Hart can chime in before we go too far and start designing an even more convoluted solution...
-
@Trivalve There is no "Comms" protocol in HISE - or JUCE for that matter. So you would have to wrap your own. @Christoph-Hart could chime in but I'd be surprised if this request was close to the top of the scheduled enhancements - given we have a fairly big list of stuff we all want - and this is very niche and seems to have a (partial at least) solution outlined above....
-
@Lindon As interesting as it is, that solution would be hard to work into anything more than a personal use plugin, unless there's a way to detect if plugins are loaded in different project files in order to create 'channels' as lined out in the above experiment. Maybe I should check some JUCE forums to try and see what other people might be trying.
-
@Trivalve Found that:
https://forum.juce.com/t/communication-between-plug-in-instances-multi-input-fx/17315/3 -
I wouldn't try to use the JSON file approach in a real project, seems way too hacky.
The problem with interprocess communication is memory management and since there is no one single solution it usually requires getting your hands dirty in C++ (or even C) with the specs you had in mind.
-
@Christoph-Hart My thoughts exactly, it just seemed pretty hacky. I wouldn't know where to even begin on adding C++ code to a HISE project, I'm honestly very new to working with open-source software of any kind, but that seems to be the solution - JUCE's SharedResourcePointer thingamajig. I've worked with code before, including C++ (not that I remember much of it because it's been so long), so I'm confident I could learn, but I haven't got the foggiest clue where to start. Or even where the C++ would get put, I don't know if HISE itself has support for C++ or if I'd need to do that within JUCE.
I noticed that when all instances of the plugin are closed the memory shared is deleted - but is there a way to do that when a single instance is closed? Just deleting the data that plugin was contributing? I assume there is, but I've not worked with JUCE before at all aside from a brief attempt.
-
Yes I am already using the SharedResourcePointer class in a few things - it's used to share image resources and other stuff across plugin instances.
However this is just a tool for sharing data and to setup a communication between instances with callbacks and complex data transfers is way more complex (especially if it needs to be a wrapper for HiseScript). Also there are hosts who run each plugin instance in a different process (AFAIK Bitwig does this), so you'll run into many troubles even if you get it working on your system.
I would strongly suggest to stay away from trying to implement this feature unless it is the core feature of your plugin (like it is with MIR).
If you really need is, go C++, use HISE as C++ framework and build your inter-plugin communcation system from the ground up.
-
@Christoph-Hart Well, suppose it's time to start another attempt to learn JUCE. Thanks for all the info; I wasn't even aware that documentation existed!