Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plug memory leak calling setStateInformation() on hosted VST3 #484

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions modules/juce_audio_basics/midi/juce_MidiKeyboardState.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,17 @@ class JUCE_API MidiKeyboardState
*/
void removeListener (Listener* listener);

// SD make these public
void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity);
void noteOffInternal (int midiChannel, int midiNoteNumber, float velocity);

private:
//==============================================================================
CriticalSection lock;
std::atomic<uint16> noteStates[128];
MidiBuffer eventsToAdd;
ListenerList<Listener> listeners;

void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity);
void noteOffInternal (int midiChannel, int midiNoteNumber, float velocity);

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState)
};

Expand Down
16 changes: 14 additions & 2 deletions modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,8 @@ class WavAudioFormatReader final : public AudioFormatReader
int cueNoteIndex = 0;
int cueLabelIndex = 0;
int cueRegionIndex = 0;
// SD move chunkType declaration here, add new state variable prevChunkType
int chunkType = 0, prevChunkType = 0;

StringMap dict;

Expand Down Expand Up @@ -1255,9 +1257,14 @@ class WavAudioFormatReader final : public AudioFormatReader

while ((uint64) input->getPosition() < end && ! input->isExhausted())
{
auto chunkType = input->readInt();
// SD keep track of previous chunk type for later comparison
prevChunkType = chunkType;
chunkType = input->readInt();
auto length = (uint32) input->readInt();
auto chunkEnd = input->getPosition() + length + (length & 1);
// SD after any chunk except "data", advance by chunk length rounded up to next multiple of 2
// (some WAV files don't round up length of the data chunk)
auto chunkEnd = input->getPosition() + length;
if (chunkType != chunkName("data")) chunkEnd += (length & 1);

if (chunkType == chunkName ("fmt "))
{
Expand Down Expand Up @@ -1458,6 +1465,11 @@ class WavAudioFormatReader final : public AudioFormatReader
input->readIntoMemoryBlock (tracktion, (ssize_t) length);
dict[WavAudioFormat::tracktionLoopInfo] = tracktion.toString();
}
// SD If unknown chunk type seen after "data", we might have had to advance by 1 byte after all
else if (prevChunkType == chunkName("data"))
{
chunkEnd = input->getPosition() + 1;
}
else if (chunkEnd <= input->getPosition())
{
break;
Expand Down
24 changes: 12 additions & 12 deletions modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,13 @@ namespace AAXClasses
AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::LFE, AudioChannelSet::topFrontLeft,
AudioChannelSet::topFrontRight, AudioChannelSet::topRearLeft, AudioChannelSet::topRearRight } },

{ AAX_eStemFormat_7_0_6, { AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide,
AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::topFrontLeft, AudioChannelSet::topFrontRight,
AudioChannelSet::topSideLeft, AudioChannelSet::topSideRight, AudioChannelSet::topRearLeft, AudioChannelSet::topRearRight } },
//{ AAX_eStemFormat_7_0_6, { AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide,
// AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::topFrontLeft, AudioChannelSet::topFrontRight,
// AudioChannelSet::topSideLeft, AudioChannelSet::topSideRight, AudioChannelSet::topRearLeft, AudioChannelSet::topRearRight } },

{ AAX_eStemFormat_7_1_6, { AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide,
AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::LFE, AudioChannelSet::topFrontLeft, AudioChannelSet::topFrontRight,
AudioChannelSet::topSideLeft, AudioChannelSet::topSideRight, AudioChannelSet::topRearLeft, AudioChannelSet::topRearRight } },
//{ AAX_eStemFormat_7_1_6, { AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide,
// AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::LFE, AudioChannelSet::topFrontLeft, AudioChannelSet::topFrontRight,
// AudioChannelSet::topSideLeft, AudioChannelSet::topSideRight, AudioChannelSet::topRearLeft, AudioChannelSet::topRearRight } },

{ AAX_eStemFormat_9_0_4, { AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::wideLeft, AudioChannelSet::wideRight,
AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide, AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear,
Expand Down Expand Up @@ -265,8 +265,8 @@ namespace AAXClasses
AAX_eStemFormat_5_1_4,
AAX_eStemFormat_7_0_4,
AAX_eStemFormat_7_1_4,
AAX_eStemFormat_7_0_6,
AAX_eStemFormat_7_1_6,
//AAX_eStemFormat_7_0_6,
//AAX_eStemFormat_7_1_6,
AAX_eStemFormat_9_0_4,
AAX_eStemFormat_9_1_4,
AAX_eStemFormat_9_0_6,
Expand Down Expand Up @@ -341,8 +341,8 @@ namespace AAXClasses
if (set == AudioChannelSet::create5point1point4()) return AAX_eStemFormat_5_1_4;
if (set == AudioChannelSet::create7point0point4()) return AAX_eStemFormat_7_0_4;
if (set == AudioChannelSet::create7point1point4()) return AAX_eStemFormat_7_1_4;
if (set == AudioChannelSet::create7point0point6()) return AAX_eStemFormat_7_0_6;
if (set == AudioChannelSet::create7point1point6()) return AAX_eStemFormat_7_1_6;
//if (set == AudioChannelSet::create7point0point6()) return AAX_eStemFormat_7_0_6;
//if (set == AudioChannelSet::create7point1point6()) return AAX_eStemFormat_7_1_6;
if (set == AudioChannelSet::create9point0point4()) return AAX_eStemFormat_9_0_4;
if (set == AudioChannelSet::create9point1point4()) return AAX_eStemFormat_9_1_4;
if (set == AudioChannelSet::create9point0point6()) return AAX_eStemFormat_9_0_6;
Expand Down Expand Up @@ -389,8 +389,8 @@ namespace AAXClasses
case AAX_eStemFormat_5_1_4: return AudioChannelSet::create5point1point4();
case AAX_eStemFormat_7_0_4: return AudioChannelSet::create7point0point4();
case AAX_eStemFormat_7_1_4: return AudioChannelSet::create7point1point4();
case AAX_eStemFormat_7_0_6: return AudioChannelSet::create7point0point6();
case AAX_eStemFormat_7_1_6: return AudioChannelSet::create7point1point6();
//case AAX_eStemFormat_7_0_6: return AudioChannelSet::create7point0point6();
//case AAX_eStemFormat_7_1_6: return AudioChannelSet::create7point1point6();
case AAX_eStemFormat_9_0_4: return AudioChannelSet::create9point0point4();
case AAX_eStemFormat_9_1_4: return AudioChannelSet::create9point1point4();
case AAX_eStemFormat_9_0_6: return AudioChannelSet::create9point0point6();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,12 @@ class LegacyAudioParametersWrapper
return params.contains (param);
}

// SD Hack: make this public
Array<AudioProcessorParameter*> params;

private:
const AudioProcessorParameterGroup* processorGroup = nullptr;
AudioProcessorParameterGroup ownedGroup;
Array<AudioProcessorParameter*> params;
bool legacyParamIDs = false, usingManagedParameters = false;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -949,8 +949,19 @@ struct VSTPluginInstance final : public AudioPluginInstance,
String getName (int maximumStringLength) const override
{
if (name.isEmpty())
return pluginInstance.getTextForOpcode (getParameterIndex(),
Vst2::effGetParamName);
{
#if 1
String name0 = pluginInstance.getTextForOpcode(getParameterIndex(), Vst2::effGetParamName);
Vst2::VstParameterProperties props;
if (pluginInstance.dispatch(Vst2::effGetParameterProperties, getParameterIndex(), 0, &props, 0) && props.label[0])
{
String name1 = String(props.label);
return name1.length() > name0.length() ? name1 : name0;
}
else
#endif
return pluginInstance.getTextForOpcode(getParameterIndex(), Vst2::effGetParamName);
}

if (name.length() <= maximumStringLength)
return name;
Expand Down Expand Up @@ -1651,16 +1662,16 @@ struct VSTPluginInstance final : public AudioPluginInstance,
case Vst2::audioMasterBeginEdit:
if (auto* param = getParameters()[index])
param->beginChangeGesture();
else
jassertfalse; // Invalid parameter index!
// else
// jassertfalse; // Invalid parameter index!

break;

case Vst2::audioMasterEndEdit:
if (auto* param = getParameters()[index])
param->endChangeGesture();
else
jassertfalse; // Invalid parameter index!
// else
// jassertfalse; // Invalid parameter index!

break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,9 @@ void AudioProcessor::processBypassed (AudioBuffer<floatType>& buffer, MidiBuffer
// an identical amount of latency. Without identical latency in
// processBlockBypassed a host's latency compensation could shift the audio
// passing through your bypassed plug-in forward in time.
jassert (getLatencySamples() == 0);

// SD commented this out to avoid too many debug breaks when working with random plug-ins
//jassert (getLatencySamples() == 0);

for (int ch = getMainBusNumInputChannels(); ch < getTotalNumOutputChannels(); ++ch)
buffer.clear (ch, 0, buffer.getNumSamples());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,9 @@ class JUCE_API AudioProcessorParameterWithID : public HostedAudioProcessorPara
const String paramID;

/** Provides access to the parameter's name. */
const String name;
// SD make this volatile and add setName()
/*const*/ String name;
void setName(String newName) { name = newName; }

/** Provides access to the parameter's label. */
const String label;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -779,8 +779,14 @@ class AudioDeviceSettingsPanel : public Component,
if (exactlyEqual (currentRate, 0.0))
currentRate = 48000.0;

// SD had to fix something here
int lastbs = -1;
for (auto bs : currentDevice->getAvailableBufferSizes())
bufferSizeDropDown->addItem (String (bs) + " samples (" + String (bs * 1000.0 / currentRate, 1) + " ms)", bs);
{
if (bs == lastbs) continue;
lastbs = bs;
bufferSizeDropDown->addItem(String(bs) + " samples (" + String(bs * 1000.0 / currentRate, 1) + " ms)", bs);
}

bufferSizeDropDown->setSelectedId (currentDevice->getCurrentBufferSizeSamples(), dontSendNotification);
bufferSizeDropDown->onChange = [this] { updateConfig (false, false, false, true); };
Expand Down
14 changes: 13 additions & 1 deletion modules/juce_gui_basics/widgets/juce_ListBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,10 +462,16 @@ class ListBox::ListViewport final : public Viewport,
else if (row >= lastWholeIndex)
{
setViewPosition (getViewPositionX(),
jmax (0, (row + 1) * rowH - getMaximumVisibleHeight()));
jmax (0, (row + 1) * rowH));
}
}

// SD added
void scrollToEnsureRowIsVisibleAndCentred(const int row, const int rowH)
{
setViewPosition(getViewPositionX(), jmax(0, row * rowH - getMaximumVisibleHeight() / 2));
}

void paint (Graphics& g) override
{
if (isOpaque())
Expand Down Expand Up @@ -908,6 +914,12 @@ void ListBox::scrollToEnsureRowIsOnscreen (const int row)
viewport->scrollToEnsureRowIsOnscreen (row, getRowHeight());
}

// SD added
void juce::ListBox::scrollToEnsureRowIsVisibleAndCentred (const int row)
{
viewport->scrollToEnsureRowIsVisibleAndCentred(row, getRowHeight());
}

//==============================================================================
bool ListBox::keyPressed (const KeyPress& key)
{
Expand Down
3 changes: 3 additions & 0 deletions modules/juce_gui_basics/widgets/juce_ListBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,9 @@ class JUCE_API ListBox : public Component,
/** Scrolls if necessary to make sure that a particular row is visible. */
void scrollToEnsureRowIsOnscreen (int row);

// SD Added
void scrollToEnsureRowIsVisibleAndCentred (const int row);

/** Returns a reference to the vertical scrollbar. */
ScrollBar& getVerticalScrollBar() const noexcept;

Expand Down