Hey there. I am building a Sidechain compression plugin which allows you to get a Sidechain input from another track where the DAW doesn’t support sidechaining. For this, I made use of the Singleton structure in JUCE to be able to share data between the two instances (one on the source, one on the target track), where the sending instance puts the data it receives in processBlock in a AudioBuffer object in my Singleton struct and the receiving instance is reading that and copies it into the actual buffer by doing
AudioBuffer<float>& remoteBuffer = singleton->remoteBuffer;
if (remoteBuffer.getNumSamples() > 0)
This works, but when I’m listening I can hear that the track with the receiving end has some stuttering in the audio signal. Is my attempt too slow? Thanks!
makeCopyOf doesn’t only copy the samples, it can/will also reallocate the buffer. It has the argument that makes it attempt to not reallocate, though. You should not ever allocate memory in the audio processing thread.
However, I suspect there are other, much worse flaws, in your design at the moment. Passing audio data between plugin instances is a very complicated thing to attempt and there are no guarantees it can even be made to work.
Yea I recognized that it’s complicated but generally speaking when I’m sharing a buffer via a shared memory and only pass references instead of copying, I should be able to have no stuttering in the buffers as there’s nothing copied. I just hope it doesn’t involve any thread difficulties and/or memory lock stuff. Is there maybe any other attempt?
As already pointed out, makeCopyOf should not be used in the audio thread, although it has a flag to avoid reallocation it will not guarantee you to not allocate if I get it right. copyFrom is the function to use if you are copying on the audio thread.
However, I doubt your design works stable. Just consider those totally possible scenarios:
The host processes all plugins in one thread. However it choses to sometimes process the source plugin before the receiver plugin and sometimes does it the other way round
The host renders plugins on multiple threads. The source plugin accesses the shared buffer at the very same time as the destination plugin does
The host renders plugins in separate processes. Both plugin instances create an own instance of your singleton in their own process
The host decides to call the source plugin with a different block size than the destination plugin
Judging from the code snippet I see, I would expect all those cases to lead to a fail or massive drop of buffers / discontinuity in the audio signal.
Haha, FCPX doesn’t even do aux tracks, so where would it send the side chain to? FCPX is unsuitable for anything audio beyond copying a clip in. Granted, you can add effects on a clip and automate, but that’s as good as it gets.
Cubase Elements (the cheapest version) has no sidechain support and upgrading is pretty expensive so I thought my idea might be nice! But if it won’t work, it won’t There are some plugins though which have exactly this sidechain support I wanted to do so I wonder how they got it working
Maybe those plugins are using a shared thread-safe queue (ring buffer) and add some latency…? That way there could be at least some chance the receiving plugins will have enough audio to work with. Or maybe the developers of those plugins have asked Steinberg how it could be done inside Cubase Elements…
Yea exactly. Even though there are solutions I’m very interested in seeing how they achieved it. I’m eager to learn as JUCE is an extremely interesting framework for me (I’m coming from game development)
It basically allows you to do quite simple “black box” plugins, similar to simple guitar pedals or MIDI controlled hardware synths. Anything more complicated will be a world of pain. Might be possible to do or not. (And that isn’t even really Juce’s fault, the plugin formats and APIs are just quite limited in what they expect you to do.)