From 78c8fcbda16670e597fb1417732f1d4adebb9b37 Mon Sep 17 00:00:00 2001 From: hogliux Date: Tue, 20 Jun 2017 16:09:22 +0100 Subject: [PATCH] VST2 Hosting: Always ensure that the buffer passed to the plug-in has at least the maximum number of channels that the VST2 plug-in supports --- .../format_types/juce_VSTPluginFormat.cpp | 67 +++++++++++++++---- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index d2b7a25989..329fb48fe7 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -864,7 +864,15 @@ struct VSTPluginInstance : public AudioPluginInstance, dispatch (plugInOpcodeSetSampleFloatType, 0, (pointer_sized_int) vstPrecision, 0, 0); } - tempBuffer.setSize (jmax (1, vstEffect->numInputChannels), samplesPerBlockExpected); + auto maxChannels = jmax (1, jmax (vstEffect->numInputChannels, vstEffect->numOutputChannels)); + + tmpBufferFloat .setSize (maxChannels, samplesPerBlockExpected); + tmpBufferDouble.setSize (maxChannels, samplesPerBlockExpected); + + channelBufferFloat .calloc (static_cast (maxChannels)); + channelBufferDouble.calloc (static_cast (maxChannels)); + + outOfPlaceBuffer.setSize (jmax (1, vstEffect->numOutputChannels), samplesPerBlockExpected); if (! isPowerOn) setPower (true); @@ -891,7 +899,13 @@ struct VSTPluginInstance : public AudioPluginInstance, setPower (false); } - tempBuffer.setSize (1, 1); + channelBufferFloat.free(); + tmpBufferFloat.setSize (0, 0); + + channelBufferDouble.free(); + tmpBufferDouble.setSize (0, 0); + + outOfPlaceBuffer.setSize (1, 1); incomingMidi.clear(); midiEventsToSend.freeEvents(); @@ -909,13 +923,13 @@ struct VSTPluginInstance : public AudioPluginInstance, void processBlock (AudioBuffer& buffer, MidiBuffer& midiMessages) override { jassert (! isUsingDoublePrecision()); - processAudio (buffer, midiMessages); + processAudio (buffer, midiMessages, tmpBufferFloat, channelBufferFloat); } void processBlock (AudioBuffer& buffer, MidiBuffer& midiMessages) override { jassert (isUsingDoublePrecision()); - processAudio (buffer, midiMessages); + processAudio (buffer, midiMessages, tmpBufferDouble, channelBufferDouble); } bool supportsDoublePrecisionProcessing() const override @@ -1462,12 +1476,19 @@ private: CriticalSection lock; bool wantsMidiMessages = false, initialised = false, isPowerOn = false; mutable StringArray programNames; - AudioBuffer tempBuffer; + AudioBuffer outOfPlaceBuffer; + CriticalSection midiInLock; MidiBuffer incomingMidi; VSTMidiEventList midiEventsToSend; VstTimingInformation vstHostTime; + AudioBuffer tmpBufferFloat; + HeapBlock channelBufferFloat; + + AudioBuffer tmpBufferDouble; + HeapBlock channelBufferDouble; + static pointer_sized_int handleCanDo (const char* name) { static const char* canDos[] = { "supplyIdle", @@ -1648,9 +1669,12 @@ private: //============================================================================== template - void processAudio (AudioBuffer& buffer, MidiBuffer& midiMessages) + void processAudio (AudioBuffer& buffer, MidiBuffer& midiMessages, + AudioBuffer& tmpBuffer, + HeapBlock& channelBuffer) { - auto numSamples = buffer.getNumSamples(); + auto numSamples = buffer.getNumSamples(); + auto numChannels = buffer.getNumChannels(); if (initialised) { @@ -1729,7 +1753,26 @@ private: _clearfp(); - invokeProcessFunction (buffer, numSamples); + // always ensure that the buffer is at least as large as the maximum number of channels + auto maxChannels = jmax (vstEffect->numInputChannels, vstEffect->numOutputChannels); + auto channels = channelBuffer.getData(); + + if (numChannels < maxChannels) + { + if (numSamples > tmpBuffer.getNumSamples()) + tmpBuffer.setSize (tmpBuffer.getNumChannels(), numSamples); + + tmpBuffer.clear(); + } + + for (int ch = 0; ch < maxChannels; ++ch) + channels[ch] = (ch < numChannels ? buffer.getWritePointer (ch) : tmpBuffer.getWritePointer (ch)); + + { + AudioBuffer processBuffer (channels, maxChannels, numSamples); + + invokeProcessFunction (processBuffer, numSamples); + } } else { @@ -1757,14 +1800,14 @@ private: } else { - tempBuffer.setSize (vstEffect->numOutputChannels, sampleFrames); - tempBuffer.clear(); + outOfPlaceBuffer.setSize (vstEffect->numOutputChannels, sampleFrames); + outOfPlaceBuffer.clear(); vstEffect->processAudioFunction (vstEffect, buffer.getArrayOfWritePointers(), - tempBuffer.getArrayOfWritePointers(), sampleFrames); + outOfPlaceBuffer.getArrayOfWritePointers(), sampleFrames); for (int i = vstEffect->numOutputChannels; --i >= 0;) - buffer.copyFrom (i, 0, tempBuffer.getReadPointer (i), sampleFrames); + buffer.copyFrom (i, 0, outOfPlaceBuffer.getReadPointer (i), sampleFrames); } }