Communication between plug-in instances / Multi-input fx


#1

Dear all

I am newbie on JUCE framework. Everything is unfamiliar with related skills.

I want to exchange data between plug-in instances such as channel ID, parameters.
Any recommended technique for this? I thought about shared memory(I didn’t check out it works in DAW environment), UDP based on OSC, 3rd-party software(thinks bad).

Anyone tried same pattern like above?

Alan


#2

Shared memory would work, but may be tricky to synchronise… Maybe look at the InterprocessConnection class, ValueTreeSynchroniser, etc


#3

I just implemented something like that. Shared memory was my first approach, but there is a problem with that. On Windows shared memory behaves pretty much like a smart pointer. The last holder of the shared memory deletes the shared memory object when it is no longer needed. On posix systems shared memory is created by a server and clients can connect to it. I don’t think there is a way to transfer ownership. This is a problem as the plugin that acts as a server can be deleted, while it is still being used by the other process.

So far so good. In my case I wanted to implement communication between plugins. At this point in time I believed that all plugins are running in the same process. So I just implemented a communication class and used a juce::SharedResourcePointer to have the same instance available in all plugin instances. When a plugin gets instantiated it registers itself. Now other instances of the plugin can request a list of all instances. I had to implement a pretty complicated connection mechanism to make sure that you are not accessing an instance of a plugin that is no longer available. Now with AU v3 things are going to change as plugins might run in different processes. I’ll have to look into that. I think running plugins in different processes is optional but I’m not sure yet. I really hope that there is/will be an option to run plugins of the same kind in the same process.

Shared Memory:
You need to create a shared memory object that is available all the time. If you only need a Windows implementation things are easier as your first instance of your plugin can create the shared memory block, all other instances are able to use it and the last instance will delete it automatically. If you need an implementation for posix (OS X etc.) systems as well, you probably have to use a service that creates the shared memory block. You might wanna take a look at the boost shared memory implementation as you can use their implementation to load container into shared memory and you don’t have to worry about allocation.

InterprocessConnection:
Before I used the SharedResourcePointer I had an implementation based on the juce::InterprocessConnection. You have to implement some message handling, but you don’t have to worry that much about synchronization. I used broadcast messages (juce::MessageManager) to discover all plugin instances. An instance of a plugin sent out a discover message and all other instances answered with offers that included the name of their pipe (yes I forgot to mention, I used pipes!).


#4

Dear Jan_Schwers

Thanks, Jan. Maybe I am too late to respond your post. My target was macOS now, so I tried to implement shared things using boost interprocess. Boost::interprocess library is very useful for allocating shared memory block, and it works smoothly when I read/write data even if it is customized type. Currently, it works based on background thread for observing data changed, but I want to make it works on condition variable as smarter than. It is so complicated for solving interprocess_lock exception issues. Will keep that hard.

Regards,
Alan


#5

Hey,
does that works beetwen more then one Plugin Host?
i wrote a class for me which runs in a background with a master and some slaves, a little bit like I²C.
I done it with some public variables. It works fine but isn’t Crossover if u running more then one host.
Work that with shared memory over some hosts? that would be great :slight_smile:


#6

Dear Teauma

I didn’t test it in two different DAW(e.g. Pro Tools - Reaper). But it works in case of same type of daw(Reaper), but each process(application). Maybe it can be described as different session.
The concept of Interprocess is literally “Inter Process”. So, if it fulfill, it should be done in that case.

Maybe the key concept of I2C is related with physical characteristics I guess (capacitance or one -wire protocol based on address system), so I cannot sympathize with your description.

Your master and slave plug-ins are same type? If so you can use static variables for communication, and it limited in one host program.

It’s very interesting topic, not only sound work, but also programming. Have fun!

Regards,
Alan