Recently I attempted to enable VST3 support on several of our virtual instrument products that is developed using very old JUCE3. They relies on many JUCE3-specific APIs so that I cannot update its dependent JUCE to current version. After some work, the plugin builds and can be loaded by Cubase 12. However, when I try to create multiple instrument tracks and play on one of them, other non-playing instrument instances produce crappy audio outputs that hears like very short slices from the playing instance.
This issue only occur when Cubase’s Multithread processing and ASIO Guard features are both enabled, and the plugin is loaded as VST3 (we made the same dynamic library loadable as VST2/VST3/AU/AAX). It even happens when I load different instruments (developed on same JUCE3 code base)!
If the plugin is loaded as VST2 by Cubase, it won’t happen; if Cubase ASIO Guard is disabled, it won’t happen; it won’t happen on all other host DAWs like Logic Pro, REAPER.
I made further dive on the runtime behavior of these plugin instances, and I found that:
- When there are unexpected audio outputs, the address of the audio buffer (which is actually provided from VST3’s
process
callback) are same. - I have set zero on the beginning of the
processBlock
but it won’t solve the problem at all. - If I create a separate audio buffer and perform all rendering/post processing on that, and copy the contents back to the API-provided buffer at last, it would greatly reduce the issue (become very rare).
All these gives me a feel that these buffers are not exclusively accessed by threads of these plugin instances, and they are accidentally contaminated by other plugin instances.
I then tried to find the difference on juce_VST3_Wrapper.cpp
between JUCE3 and current version of JUCE, especially processing callback process (Vst::ProcessData&)
. Both have lock related code const ScopedLock sl (pluginInstance->getCallbackLock());
before processBlock
calls.
I also tried to backport the newest VST3 SDK to our very old JUCE3 codebase. After some efforts it compiles and loads, but does not solve this issue at all.
Currently I have completely no clue about the problem. As there are massive changes between JUCE3 to current codebase, I guess it won’t happen nowadays. So I write this post here to ask if anyone knows some clues about it?