VST3 and buzz

Hi,

Recently we have released a VST3 version of our plugin and some users are reporting some buzz noise.

Checking the VST3 code, it looks like that as opposed to other format, when numOutput > numInputs the buffer are not cleared.

Is this intentional ?

The code is quite complex but it looks that the issue might be here

// For input channels that are < the total number of outputs channels, copy the input over
        // the output buffer, at the appropriate JUCE channel index.
        // For input channels that are >= the total number of output channels, add the input buffer
        // pointer to the array of channel pointers.
        for (size_t inputBus = 0, initialBusIndex = 0; inputBus < (size_t) vstInputs; ++inputBus)
        {
            const auto& map = inputMap[inputBus];

            if (! map.isActive())
                continue;

            auto** busPtr = getAudioBusPointer (detail::Tag<FloatType>{}, data.inputs[inputBus]);

            for (auto i = 0; i < (int) map.size(); ++i)
            {
                const auto destIndex = initialBusIndex + (size_t) map.getJuceChannelForVst3Channel (i);

                channels.resize (jmax (channels.size(), destIndex + 1), nullptr);

                if (auto* dest = channels[destIndex])
                    FloatVectorOperations::copy (dest, busPtr[i], (int) data.numSamples);
                else
                    channels[destIndex] = busPtr[i];
// SHOULD IT BE CLEARED HERE ?
            }

            initialBusIndex += map.size();
        }

From the AudioProcessor docs for processBlock:

Note that if you have more outputs than inputs, then only those channels that
correspond to an input channel are guaranteed to contain sensible data - e.g.
in the case of 2 inputs and 4 outputs, the first two channels contain the input,
but the last two channels may contain garbage, so you should be careful not to
let this pass through without being overwritten or cleared.

Of course, if you’ve noticed that some of the input channels contain garbage data, or the channel layout is incorrect, please let me know and I’ll take a look.

in juce_VST_wrapper, you clear (line 437)
in juce_AAX_Wrapper, you clear (line 1296)
in juce_AU_Wrapper, you clear (line 1912)

Maybe it’s more a matter of being consistent

I can clear on my end but it would means that for all other format, it will be done twice

As a side note, it looks like MultiOutSynthPluginDemo do not handle the case either

I think that’s probably a bug in the MultiOutSynthPluginDemo. It should definitely be expected that unused input channels will need clearing or overwriting. So, in AU/VST/AAX plugins you should always expect unused input channels to contain garbage, as the current behaviour may change in the future.

As another example of this behaviour being documented, the template plugin project contains the following in its processBlock:

    // In case we have more outputs than inputs, this code clears any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    // This is here to avoid people getting screaming feedback
    // when they first compile a plugin, but obviously you don't need to keep
    // this code if your algorithm always overwrites all the output channels.
    for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear (i, 0, buffer.getNumSamples());

The point about clearing buffers twice is interesting, and I’d like to investigate that a bit more if I get a chance. I’m not sure why the other formats are clearing unused input buffers, but it seems that it would be most efficient to avoid clearing in any of the wrappers, and to force the clearing to happen inside the AudioProcessor itself. This way, the plugin can choose whether to clear or overwrite the unused input channels, and there’s no chance of doing duplicate/redundant work. However, as this will only lead to a very minor performance boost, I don’t think this is a high-priority task for us at the moment.

fair enough.

You guys needs to fix the MultiOutSynthPluginDemo which still exhibits the issue and produces a loud noise in Cubase for example.

Thanks, I’ll make that change. FWIW I tested in Cubase 12, and even when the plugin explicitly clears all output buses, Cubase emits noise on the output channels under certain conditions. I think this is likely to be a bug in Cubase. There are more details here:

Improvements to the MultiOutSynthPluginDemo were merged here: