From 68e76c1dc474585d36f8ace3c265a01bdaf6dce7 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Fri, 9 Oct 2020 16:08:18 +0100 Subject: [PATCH 01/36] tracktion: Added cron job to merge develop --- .github/merge_upstream.yaml | 20 ++++++++++++++++++++ .github/update | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 .github/merge_upstream.yaml create mode 100644 .github/update diff --git a/.github/merge_upstream.yaml b/.github/merge_upstream.yaml new file mode 100644 index 000000000000..91880cd98b83 --- /dev/null +++ b/.github/merge_upstream.yaml @@ -0,0 +1,20 @@ +name: Merge Upstream +on: + workflow_dispatch: + schedule: + - cron: '0 * * * *' + +jobs: + build: + name: Merge Upstream + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: | + git fetch --prune --unshallow + - name: "Run script" + run: | + ./.github/workflows/update + env: + GH_EMAIL: ${{ secrets.GH_EMAIL }} + GH_NAME: ${{ secrets.GH_NAME }} diff --git a/.github/update b/.github/update new file mode 100644 index 000000000000..cc83df00c37c --- /dev/null +++ b/.github/update @@ -0,0 +1,32 @@ +#!/bin/sh -e + +# Use braces to load the entire script in to memory +{ + echo ** Move to repo + cd $RUNNER_WORKSPACE/JUCE + pwd + + git config --global user.email "$GH_NAME" + git config --global user.name "$GH_EMAIL" + + echo ** Updating tracktion/JUCE from juce-framework/JUCE + + git checkout develop + + echo ** Setup remote + git remote -v + git remote add upstream https://github.com/juce-framework/JUCE.git + git remote -v + + echo ** Fetch remote + git fetch upstream + + echo ** Update develop + git merge upstream/develop + git push + + echo ** Update tracktion/develop + git checkout tracktion/develop + git merge develop + git push +} \ No newline at end of file From 311745a4e155962aa8fa722476e48fd55647d120 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Fri, 9 Oct 2020 16:20:53 +0100 Subject: [PATCH 02/36] tracktion: Added merge develop workflow --- .github/{ => workflows}/merge_upstream.yaml | 3 ++- .github/{ => workflows}/update | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename .github/{ => workflows}/merge_upstream.yaml (98%) rename .github/{ => workflows}/update (100%) mode change 100644 => 100755 diff --git a/.github/merge_upstream.yaml b/.github/workflows/merge_upstream.yaml similarity index 98% rename from .github/merge_upstream.yaml rename to .github/workflows/merge_upstream.yaml index 91880cd98b83..2a396d3fb766 100644 --- a/.github/merge_upstream.yaml +++ b/.github/workflows/merge_upstream.yaml @@ -1,8 +1,9 @@ name: Merge Upstream on: - workflow_dispatch: schedule: - cron: '0 * * * *' + push: + workflow_dispatch: jobs: build: diff --git a/.github/update b/.github/workflows/update old mode 100644 new mode 100755 similarity index 100% rename from .github/update rename to .github/workflows/update From b2fd434fc034ddba849a0e0a16b1ccaaedc9cf79 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Mon, 14 Dec 2020 09:44:42 -0800 Subject: [PATCH 03/36] Tracktion: remove - from plug-ins --- .../scanning/juce_PluginListComponent.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 88c3f81835ce..82a985a1d055 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -296,7 +296,7 @@ PopupMenu PluginListComponent::createOptionsMenu() for (auto format : formatManager.getFormats()) if (format->canScanForPlugins()) - menu.addItem (PopupMenu::Item ("Remove all " + format->getName() + " plug-ins") + menu.addItem (PopupMenu::Item ("Remove all " + format->getName() + " plugins") .setEnabled (! list.getTypesForFormat (*format).isEmpty()) .setAction ([this, format] { @@ -306,18 +306,18 @@ PopupMenu PluginListComponent::createOptionsMenu() menu.addSeparator(); - menu.addItem (PopupMenu::Item (TRANS("Remove selected plug-in from list")) + menu.addItem (PopupMenu::Item (TRANS("Remove selected plugin from list")) .setEnabled (table.getNumSelectedRows() > 0) .setAction ([this] { removeSelectedPlugins(); })); - menu.addItem (PopupMenu::Item (TRANS("Remove any plug-ins whose files no longer exist")) + menu.addItem (PopupMenu::Item (TRANS("Remove any plugins whose files no longer exist")) .setAction ([this] { removeMissingPlugins(); })); menu.addSeparator(); auto selectedRow = table.getSelectedRow(); - menu.addItem (PopupMenu::Item (TRANS("Show folder containing selected plug-in")) + menu.addItem (PopupMenu::Item (TRANS("Show folder containing selected plugin")) .setEnabled (canShowFolderForPlugin (list, selectedRow)) .setAction ([this, selectedRow] { showFolderForPlugin (list, selectedRow); })); @@ -325,7 +325,7 @@ PopupMenu PluginListComponent::createOptionsMenu() for (auto format : formatManager.getFormats()) if (format->canScanForPlugins()) - menu.addItem (PopupMenu::Item ("Scan for new or updated " + format->getName() + " plug-ins") + menu.addItem (PopupMenu::Item ("Scan for new or updated " + format->getName() + " plugins") .setAction ([this, format] { scanFor (*format); })); return menu; @@ -337,10 +337,10 @@ PopupMenu PluginListComponent::createMenuForRow (int rowNumber) if (rowNumber >= 0 && rowNumber < tableModel->getNumRows()) { - menu.addItem (PopupMenu::Item (TRANS("Remove plug-in from list")) + menu.addItem (PopupMenu::Item (TRANS("Remove plugin from list")) .setAction ([this, rowNumber] { removePluginItem (rowNumber); })); - menu.addItem (PopupMenu::Item (TRANS("Show folder containing plug-in")) + menu.addItem (PopupMenu::Item (TRANS("Show folder containing plugin")) .setEnabled (canShowFolderForPlugin (list, rowNumber)) .setAction ([this, rowNumber] { showFolderForPlugin (list, rowNumber); })); } @@ -623,8 +623,8 @@ void PluginListComponent::scanFor (AudioPluginFormat& format) void PluginListComponent::scanFor (AudioPluginFormat& format, const StringArray& filesOrIdentifiersToScan) { currentScanner.reset (new Scanner (*this, format, filesOrIdentifiersToScan, propertiesToUse, allowAsync, numThreads, - dialogTitle.isNotEmpty() ? dialogTitle : TRANS("Scanning for plug-ins..."), - dialogText.isNotEmpty() ? dialogText : TRANS("Searching for all possible plug-in files..."))); + dialogTitle.isNotEmpty() ? dialogTitle : TRANS("Scanning for plugins..."), + dialogText.isNotEmpty() ? dialogText : TRANS("Searching for all possible plugin files..."))); } bool PluginListComponent::isScanning() const noexcept From 72824d1fd1704462101d63c2516676bd7379362c Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Sat, 29 Aug 2020 11:57:11 -0700 Subject: [PATCH 04/36] tracktion: Added support for fetching MIDI note names to VST and VST3 (host/plugin) --- .../VST/juce_VST_Wrapper.cpp | 17 +++++++++++ .../VST3/juce_VST3_Wrapper.cpp | 24 ++++++++++++++-- .../format_types/juce_VST3PluginFormat.cpp | 28 +++++++++++++++++++ .../format_types/juce_VSTPluginFormat.cpp | 15 ++++++++++ .../processors/juce_AudioProcessor.cpp | 5 ++++ .../processors/juce_AudioProcessor.h | 3 ++ 6 files changed, 90 insertions(+), 2 deletions(-) diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp index f0f915fa2dfd..00b993da1d9c 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -999,6 +999,7 @@ class JuceVSTWrapper : public AudioProcessorListener, case Vst2::effSetProcessPrecision: return handleSetSampleFloatType (args); case Vst2::effGetNumMidiInputChannels: return handleGetNumMidiInputChannels(); case Vst2::effGetNumMidiOutputChannels: return handleGetNumMidiOutputChannels(); + case Vst2::effGetMidiKeyName: return handleGetMidiKeyName (args); default: return 0; } } @@ -2022,6 +2023,22 @@ class JuceVSTWrapper : public AudioProcessorListener, return 0; } + pointer_sized_int handleGetMidiKeyName (VstOpCodeArguments args) + { + if (processor != nullptr) + { + String name; + Vst2::MidiKeyName* keyName = (Vst2::MidiKeyName*)args.ptr; + + if (processor->hasNameForMidiNoteNumber (keyName->thisKeyNumber, args.index, name)) + { + name.copyToUTF8 (keyName->keyName, sizeof (keyName->keyName)); + return 1; + } + } + return 0; + } + pointer_sized_int handleSetContentScaleFactor (float scale) { #if ! JUCE_MAC diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index c87a6da429fd..b7895e6a8f74 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -198,9 +198,29 @@ class JuceAudioProcessor : public Vst::IUnitInfo return kResultFalse; } + tresult PLUGIN_API hasProgramPitchNames (Vst::ProgramListID, Steinberg::int32) override + { + String name; + for (int i = 0; i < 127; i++) + if (audioProcessor->hasNameForMidiNoteNumber (i, 1, name) == kResultTrue) + return kResultTrue; + + return kResultFalse; + } + + tresult PLUGIN_API getProgramPitchName (Vst::ProgramListID, Steinberg::int32, Steinberg::int16 midiNote, Vst::String128 name) override + { + String nameOut; + if (audioProcessor->hasNameForMidiNoteNumber (midiNote, 1, nameOut)) + { + toString128 (name, nameOut); + return kResultTrue; + } + + return kResultFalse; + } + tresult PLUGIN_API getProgramInfo (Vst::ProgramListID, Steinberg::int32, Vst::CString, Vst::String128) override { return kNotImplemented; } - tresult PLUGIN_API hasProgramPitchNames (Vst::ProgramListID, Steinberg::int32) override { return kNotImplemented; } - tresult PLUGIN_API getProgramPitchName (Vst::ProgramListID, Steinberg::int32, Steinberg::int16, Vst::String128) override { return kNotImplemented; } tresult PLUGIN_API selectUnit (Vst::UnitID) override { return kNotImplemented; } tresult PLUGIN_API setUnitProgramData (Steinberg::int32, Steinberg::int32, IBStream*) override { return kNotImplemented; } Vst::UnitID PLUGIN_API getSelectedUnit() override { return Vst::kRootUnitId; } diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 9161855f8506..9793a60d674e 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -2217,6 +2217,34 @@ class VST3PluginInstance : public AudioPluginInstance return result; } + //============================================================================== + bool hasNameForMidiNoteNumber (int note, int /*midiChannel*/, juce::String& noteName) override + { + if (unitInfo != nullptr) + { + const int programListCount = unitInfo->getProgramListCount(); + + if (programListCount > 0) + { + Vst::ProgramListInfo programListInfo {}; + + if (unitInfo->getProgramListInfo (0, programListInfo) == kResultOk) + { + if (unitInfo->hasProgramPitchNames (programListInfo.id, 0) == kResultTrue) + { + Vst::String128 name; + if (unitInfo->getProgramPitchName (programListInfo.id, 0, (Steinberg::int16) note, name) == kResultTrue) + { + noteName = toString (name) ; + return true; + } + } + } + } + } + return false; + } + //============================================================================== void updateTrackProperties (const TrackProperties& properties) override { diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 647a6b55be42..bb3b2cf66c00 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -1316,6 +1316,21 @@ struct VSTPluginInstance : public AudioPluginInstance, int pluginCanDo (const char* text) const { return (int) dispatch (Vst2::effCanDo, 0, 0, (void*) text, 0); } + bool hasNameForMidiNoteNumber (int note, int midiChannel, juce::String& noteName) override + { + Vst2::MidiKeyName keyName; + memset (&keyName, 0, sizeof (keyName)); + keyName.thisProgramIndex = getCurrentProgram(); + keyName.thisKeyNumber = note; + + if (dispatch (Vst2::effGetMidiKeyName, midiChannel, 0, &keyName, 0.0f)) + { + noteName = String::createStringFromData (keyName.keyName, sizeof (keyName.keyName)); + return true; + } + return false; + } + //============================================================================== void prepareToPlay (double rate, int samplesPerBlockExpected) override { diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 040accf2e563..b03948fdd1a2 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -877,6 +877,11 @@ void AudioProcessor::setCurrentProgramStateInformation (const void* data, int si //============================================================================== void AudioProcessor::updateTrackProperties (const AudioProcessor::TrackProperties&) {} +bool AudioProcessor::hasNameForMidiNoteNumber (int, int, juce::String&) +{ + return false; +} + //============================================================================== // magic number to identify memory blocks that we've stored as XML const uint32 magicXmlNumber = 0x21324356; diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 39eac8211247..8e391efcc928 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1239,6 +1239,9 @@ class JUCE_API AudioProcessor */ virtual void updateTrackProperties (const TrackProperties& properties); + /** Gets the name of a MIDI note, if available */ + virtual bool hasNameForMidiNoteNumber (int note, int midiChannel, juce::String& name); + //============================================================================== /** Helper function that just converts an xml element into a binary blob. From e9af4980bef9720feaeccb8b97502604ccc55517 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Wed, 17 Mar 2021 19:08:15 -0700 Subject: [PATCH 05/36] Update _WIN32_IE to 501 to fix Windows build --- modules/juce_core/native/juce_BasicNativeHeaders.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_core/native/juce_BasicNativeHeaders.h b/modules/juce_core/native/juce_BasicNativeHeaders.h index 306bb536674d..217951bf057e 100644 --- a/modules/juce_core/native/juce_BasicNativeHeaders.h +++ b/modules/juce_core/native/juce_BasicNativeHeaders.h @@ -139,7 +139,7 @@ #define _UNICODE 1 #define UNICODE 1 #ifndef _WIN32_IE - #define _WIN32_IE 0x0500 + #define _WIN32_IE 0x0501 #endif #include From d6f747bc9af1c7be51e069d25913a05fd6bb2266 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Wed, 24 Mar 2021 12:43:42 +0000 Subject: [PATCH 06/36] CoreAudio: Changed latency reporting to update during audio callbacks for increased accuracy --- .../native/juce_mac_CoreAudio.cpp | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index feac8c3b476c..c9bce5346bfb 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -129,6 +129,17 @@ bool JUCE_CALLTYPE SystemAudioVolume::setGain (float gain) { return SystemVol bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { return SystemVol (kAudioDevicePropertyMute).isMuted(); } bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool mute) { return SystemVol (kAudioDevicePropertyMute).setMuted (mute); } +static double machToSeconds (UInt64 machTime) +{ + const int64_t kNanoPerS = 1000 * 1000 * 1000; + static mach_timebase_info_data_t s_timebase_info; + + if (s_timebase_info.denom == 0) + mach_timebase_info (&s_timebase_info); + + return ((machTime * s_timebase_info.numer) / double (kNanoPerS * s_timebase_info.denom)); +} + //============================================================================== struct CoreAudioClasses { @@ -730,6 +741,15 @@ class CoreAudioInternal : private Timer double getSampleRate() const { return sampleRate; } int getBufferSize() const { return bufferSize; } + void updateLatency (double now, double inputTimestamp, double outputTimestamp) + { + const auto inputLatencyTime = now - inputTimestamp; + const auto outputLatencyTime = outputTimestamp - now; + + inputLatency.store (roundToInt (inputLatencyTime * sampleRate), std::memory_order_relaxed); + outputLatency.store (roundToInt (outputLatencyTime * sampleRate), std::memory_order_relaxed); + } + void audioCallback (const AudioBufferList* inInputData, AudioBufferList* outOutputData) { @@ -808,8 +828,8 @@ class CoreAudioInternal : private Timer //============================================================================== CoreAudioIODevice& owner; - int inputLatency = 0; - int outputLatency = 0; + std::atomic inputLatency { 0 }; + std::atomic outputLatency { 0 }; int bitDepth = 32; int xruns = 0; BigInteger activeInputChans, activeOutputChans; @@ -836,14 +856,26 @@ class CoreAudioInternal : private Timer //============================================================================== static OSStatus audioIOProc (AudioDeviceID /*inDevice*/, - const AudioTimeStamp* /*inNow*/, + const AudioTimeStamp* inNow, const AudioBufferList* inInputData, - const AudioTimeStamp* /*inInputTime*/, + const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, - const AudioTimeStamp* /*inOutputTime*/, + const AudioTimeStamp* inOutputTime, void* device) { - static_cast (device)->audioCallback (inInputData, outOutputData); + auto internal = static_cast (device); + + if (inNow->mFlags & kAudioTimeStampHostTimeValid + && inInputTime->mFlags & kAudioTimeStampHostTimeValid + && inOutputTime->mFlags & kAudioTimeStampHostTimeValid) + { + internal->updateLatency (machToSeconds (inNow->mHostTime), + machToSeconds (inInputTime->mHostTime), + machToSeconds (inOutputTime->mHostTime)); + } + + internal->audioCallback (inInputData, outOutputData); + return noErr; } From b7f8d21cf9c145fb0efbc6357d9d66897172d338 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Wed, 14 Apr 2021 09:33:32 -0700 Subject: [PATCH 07/36] tracktion: only assert if transform set on top most plugin editor --- .../processors/juce_AudioProcessorEditor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp index 30249c0a5325..087d4a1117b2 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp @@ -168,7 +168,8 @@ void AudioProcessorEditor::editorResized (bool wasResized) // obliterate it! If you want to scale the whole of your UI use Desktop::setGlobalScaleFactor(), // or, for applying other transforms, consider putting the component you want to transform // in a child of the editor and transform that instead. - jassert (getTransform() == hostScaleTransform); + if (findParentComponentOfClass() == nullptr) + jassert (getTransform() == hostScaleTransform); if (wasResized) { From f1bd42a02affc5a11ae1cbbf39f2238898fddf36 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Wed, 14 Apr 2021 09:40:19 -0700 Subject: [PATCH 08/36] tracktion: fixed assert in standalone plugins --- .../Standalone/juce_StandaloneFilterApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp index cb099283a239..bb02a28ff4ec 100644 --- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp +++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp @@ -55,7 +55,7 @@ class StandaloneFilterApp : public JUCEApplication PropertiesFile::Options options; - options.applicationName = getApplicationName(); + options.applicationName = File::createLegalFileName (getApplicationName()); options.filenameSuffix = ".settings"; options.osxLibrarySubFolder = "Application Support"; #if JUCE_LINUX || JUCE_BSD From bcd927441b18a606372bfb549c6d283653dbdf51 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Wed, 14 Apr 2021 11:10:15 -0700 Subject: [PATCH 09/36] tracktion: another hack to try and fix Linux window positions --- .../format_types/juce_VSTPluginFormat.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index e052e3f25392..83dc0b562636 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2911,6 +2911,11 @@ struct VSTPluginWindow : public AudioProcessorEditor, if (safeThis != nullptr) componentMovedOrResized (true, true); }); + Timer::callAfterDelay (250, [this, safeThis] + { + if (safeThis != nullptr) + componentMovedOrResized (true, true); + }); #else componentMovedOrResized (true, true); #endif From a1f54574786ef66c526d3c5d9dd0095c2b35a1c5 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Mon, 3 May 2021 10:49:52 -0700 Subject: [PATCH 10/36] tracktion: Fixed loading VST2 shell plugins --- .../juce_audio_processors/format_types/juce_VSTPluginFormat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 6df0701f2c25..f0cf134c1b3e 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -3556,7 +3556,7 @@ void VSTPluginFormat::createPluginInstance (const PluginDescription& desc, if (auto module = ModuleHandle::findOrCreateModule (file)) { - shellUIDToCreate = desc.uniqueId; + shellUIDToCreate = desc.uniqueId != 0 ? desc.uniqueId : desc.deprecatedUid; result.reset (VSTPluginInstance::create (module, sampleRate, blockSize)); From 40f0d56cf8d9d685593b0e1fbbc21bc4ae1cb5af Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Thu, 6 May 2021 11:18:42 -0700 Subject: [PATCH 11/36] tracktion: Fixed broken VST3 after load --- .../format_types/juce_VST3Common.h | 11 +++++++++++ .../format_types/juce_VST3PluginFormat.cpp | 1 + 2 files changed, 12 insertions(+) diff --git a/modules/juce_audio_processors/format_types/juce_VST3Common.h b/modules/juce_audio_processors/format_types/juce_VST3Common.h index 8ef0fe3e43cf..93bcb312c1b8 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -974,6 +974,12 @@ class FloatCache } } + void clear() + { + for (size_t flagIndex = 0; flagIndex < flags.size(); ++flagIndex) + flags[flagIndex].exchange (0, std::memory_order_acq_rel); + } + private: static constexpr size_t numFlagBits = 8 * sizeof (FlagType); @@ -1011,6 +1017,11 @@ class CachedParamValues template void ifSet (Callback&& callback) { floatCache.ifSet (std::forward (callback)); } + void clear() + { + floatCache.clear(); + } + private: std::vector paramIds; FloatCache floatCache; diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 50fa8301d275..4b20bb6ea9f3 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -2838,6 +2838,7 @@ class VST3PluginInstance : public AudioPluginInstance auto* vst3Param = static_cast (parameter); vst3Param->setValueFromEditor ((float) editController->getParamNormalized (vst3Param->getParamID())); } + cachedParamValues.clear(); } bool setStateFromPresetFile (const MemoryBlock& rawData) From b16b9be1c4d7b405d5060344f4deb510220007ba Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Thu, 6 May 2021 12:25:34 -0700 Subject: [PATCH 12/36] tracktion: Proper fix for VST3 issue --- .../format_types/juce_VST3Common.h | 17 +++-------------- .../format_types/juce_VST3PluginFormat.cpp | 1 - 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_VST3Common.h b/modules/juce_audio_processors/format_types/juce_VST3Common.h index 93bcb312c1b8..8d75433acce9 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -942,9 +942,9 @@ class FloatCache void set (size_t index, float value) { jassert (index < size()); - values[index].store (value, std::memory_order_relaxed); - flags[index / numFlagBits].fetch_or ((FlagType) 1 << (index % numFlagBits), - std::memory_order_acq_rel); + const auto previous = values[index].exchange (value, std::memory_order_relaxed); + const auto bit = previous == value ? 0 : (FlagType) 1 << (index % numFlagBits); + flags[index / numFlagBits].fetch_or (bit, std::memory_order_acq_rel); } float get (size_t index) const noexcept @@ -974,12 +974,6 @@ class FloatCache } } - void clear() - { - for (size_t flagIndex = 0; flagIndex < flags.size(); ++flagIndex) - flags[flagIndex].exchange (0, std::memory_order_acq_rel); - } - private: static constexpr size_t numFlagBits = 8 * sizeof (FlagType); @@ -1017,11 +1011,6 @@ class CachedParamValues template void ifSet (Callback&& callback) { floatCache.ifSet (std::forward (callback)); } - void clear() - { - floatCache.clear(); - } - private: std::vector paramIds; FloatCache floatCache; diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 4b20bb6ea9f3..50fa8301d275 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -2838,7 +2838,6 @@ class VST3PluginInstance : public AudioPluginInstance auto* vst3Param = static_cast (parameter); vst3Param->setValueFromEditor ((float) editController->getParamNormalized (vst3Param->getParamID())); } - cachedParamValues.clear(); } bool setStateFromPresetFile (const MemoryBlock& rawData) From c54294d048ab2bdfc6504afe9ec9fdbeda46f2d0 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Fri, 25 Jun 2021 14:54:51 +0100 Subject: [PATCH 13/36] Tracktion: Fixed use of BufferingAudioReader with compressed input readers --- .../format/juce_BufferingAudioFormatReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp index 7966cea432cb..c50cf09384d1 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp @@ -131,7 +131,7 @@ int BufferingAudioReader::useTimeSlice() bool BufferingAudioReader::readNextBufferChunk() { - auto pos = nextReadPosition.load(); + auto pos = (nextReadPosition.load() / samplesPerBlock) * samplesPerBlock; auto endPos = jmin (lengthInSamples, pos + numBlocks * samplesPerBlock); OwnedArray newBlocks; From ec0d37e9871921f04f1e343f3848c559ce1ee579 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Thu, 15 Jul 2021 16:52:34 +0100 Subject: [PATCH 14/36] Tracktion: Fixed a Linux compile error --- .../format_types/juce_VSTPluginFormat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 02c0bcebdb8e..b2595b70bc69 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2962,10 +2962,10 @@ struct VSTPluginWindow : public AudioProcessorEditor, if (safeThis != nullptr) safeThis->componentMovedOrResized (true, true); }); - Timer::callAfterDelay (250, [this, safeThis] + Timer::callAfterDelay (250, [safeThis = SafePointer { this }] { if (safeThis != nullptr) - componentMovedOrResized (true, true); + safeThis->componentMovedOrResized (true, true); }); #else componentMovedOrResized (true, true); From 871a4130e5f7cdf59ffd3d39167081b086c10a06 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Fri, 6 Aug 2021 10:32:38 -0700 Subject: [PATCH 15/36] tracktion: fix endless paint messages when resizing header --- modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp index 82558580e2c5..79662e91073d 100644 --- a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp +++ b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp @@ -174,7 +174,7 @@ void TableHeaderComponent::setColumnWidth (const int columnId, const int newWidt { if (auto* ci = getInfoForId (columnId)) { - if (ci->width != newWidth) + if (ci->width != jlimit (ci->minimumWidth, ci->maximumWidth, newWidth)) { auto numColumns = getNumColumns (true); From 5693ece228f42cdacd08864737282ddc9eb1fc0c Mon Sep 17 00:00:00 2001 From: David Rowland Date: Mon, 11 Oct 2021 17:33:32 +0100 Subject: [PATCH 16/36] Tracktion: Made AudioProcessorParameterWithID inherit from AudioPluginInstance::HostedParameter --- .../utilities/juce_AudioProcessorParameterWithID.cpp | 1 + .../utilities/juce_AudioProcessorParameterWithID.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp index c8cb10819c5e..5d0f6f4a9fba 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp @@ -33,6 +33,7 @@ AudioProcessorParameterWithID::AudioProcessorParameterWithID (const String& idTo : paramID (idToUse), name (nameToUse), label (labelToUse), category (categoryToUse) {} AudioProcessorParameterWithID::~AudioProcessorParameterWithID() {} +String AudioProcessorParameterWithID::getParameterID() const { return paramID; } String AudioProcessorParameterWithID::getName (int maximumStringLength) const { return name.substring (0, maximumStringLength); } String AudioProcessorParameterWithID::getLabel() const { return label; } AudioProcessorParameter::Category AudioProcessorParameterWithID::getCategory() const { return category; } diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h index 9b43de7f440d..e06766b99a64 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h @@ -33,7 +33,7 @@ namespace juce @tags{Audio} */ -class JUCE_API AudioProcessorParameterWithID : public AudioProcessorParameter +class JUCE_API AudioProcessorParameterWithID : public AudioPluginInstance::HostedParameter { public: /** The creation of this object requires providing a name and ID which will be @@ -59,6 +59,7 @@ class JUCE_API AudioProcessorParameterWithID : public AudioProcessorParameter /** Provides access to the parameter's category. */ const Category category; + String getParameterID() const override; String getName (int) const override; String getLabel() const override; Category getCategory() const override; From 73842dc2a1413ec38e71d785f972aeaa00f2ba8b Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Thu, 14 Oct 2021 06:56:21 -0700 Subject: [PATCH 17/36] tracktion: fixed crash in empty grid --- modules/juce_gui_basics/layout/juce_Grid.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/juce_gui_basics/layout/juce_Grid.cpp b/modules/juce_gui_basics/layout/juce_Grid.cpp index f27b82b6f8cc..cbd891823fe4 100644 --- a/modules/juce_gui_basics/layout/juce_Grid.cpp +++ b/modules/juce_gui_basics/layout/juce_Grid.cpp @@ -1004,6 +1004,8 @@ float Grid::TrackInfo::getAbsoluteSize (float relativeFractionalUnit) const void Grid::performLayout (Rectangle targetArea) { const auto itemsAndAreas = AutoPlacement().deduceAllItems (*this); + if (itemsAndAreas.isEmpty()) + return; auto implicitTracks = AutoPlacement::createImplicitTracks (*this, itemsAndAreas); From 0e4169eb68a39ebf99e834ec08a9f850f9227ef5 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Tue, 9 Nov 2021 09:49:23 -0800 Subject: [PATCH 18/36] tracktion: Added AffineTransform::horizontalFlip --- modules/juce_graphics/geometry/juce_AffineTransform.cpp | 6 ++++++ modules/juce_graphics/geometry/juce_AffineTransform.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/modules/juce_graphics/geometry/juce_AffineTransform.cpp b/modules/juce_graphics/geometry/juce_AffineTransform.cpp index 86713c85b3a3..599aa7d0e921 100644 --- a/modules/juce_graphics/geometry/juce_AffineTransform.cpp +++ b/modules/juce_graphics/geometry/juce_AffineTransform.cpp @@ -184,6 +184,12 @@ AffineTransform AffineTransform::verticalFlip (float height) noexcept 0.0f, -1.0f, height }; } +AffineTransform AffineTransform::horizontalFlip (float width) noexcept +{ + return { -1.0f, 0.0f, width, + 0.0f, 1.0f, 0.0f }; +} + AffineTransform AffineTransform::inverted() const noexcept { double determinant = getDeterminant(); diff --git a/modules/juce_graphics/geometry/juce_AffineTransform.h b/modules/juce_graphics/geometry/juce_AffineTransform.h index 56f2faac8054..c53f511a7b55 100644 --- a/modules/juce_graphics/geometry/juce_AffineTransform.h +++ b/modules/juce_graphics/geometry/juce_AffineTransform.h @@ -206,6 +206,10 @@ class JUCE_API AffineTransform final */ static AffineTransform verticalFlip (float height) noexcept; + /** Returns a transform that will flip coordinates horizontally within a window of the given width. + */ + static AffineTransform horizontalFlip (float width) noexcept; + /** Returns a matrix which is the inverse operation of this one. Some matrices don't have an inverse - in this case, the method will just return From 23ae03ef85cdfa2e86f3ecc2b9f7c7494f3f61c5 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Thu, 20 Jan 2022 14:15:05 -0800 Subject: [PATCH 19/36] Update merge_upstream.yaml --- .github/workflows/merge_upstream.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/merge_upstream.yaml b/.github/workflows/merge_upstream.yaml index 2a396d3fb766..2c94348ffcf1 100644 --- a/.github/workflows/merge_upstream.yaml +++ b/.github/workflows/merge_upstream.yaml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + token: ${{ secrets.TOKEN }} - run: | git fetch --prune --unshallow - name: "Run script" From 0e20630c452084d79eb6061f055f9bceab569f86 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Fri, 11 Feb 2022 11:23:38 -0800 Subject: [PATCH 20/36] tracktion: Confirm before removing plugins --- .../scanning/juce_PluginListComponent.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 3dda6c4533d0..33b955a50c6f 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -300,8 +300,11 @@ PopupMenu PluginListComponent::createOptionsMenu() .setEnabled (! list.getTypesForFormat (*format).isEmpty()) .setAction ([this, format] { - for (auto& pd : list.getTypesForFormat (*format)) - list.removeType (pd); + auto title = "Remove all " + format->getName() + " plugins?"; + auto message = "Are you sure you want to remove all " + format->getName() + " plugins?"; + if (AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, title, message, TRANS("Yes"), TRANS("No"))) + for (auto& pd : list.getTypesForFormat (*format)) + list.removeType (pd); })); menu.addSeparator(); From ea14d28bc9c6126da9fdc7663cebbc67a2dba739 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Mon, 28 Feb 2022 17:30:30 +0000 Subject: [PATCH 21/36] NamedPipe: Fixed a deadlock on close --- modules/juce_core/native/juce_posix_NamedPipe.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/juce_core/native/juce_posix_NamedPipe.cpp b/modules/juce_core/native/juce_posix_NamedPipe.cpp index 0e6e678324d6..2a0de7b8de4a 100644 --- a/modules/juce_core/native/juce_posix_NamedPipe.cpp +++ b/modules/juce_core/native/juce_posix_NamedPipe.cpp @@ -246,12 +246,17 @@ class NamedPipe::Pimpl void NamedPipe::close() { + { + ScopedReadLock sl (lock); + + if (pimpl != nullptr) + pimpl->stopReadOperation = true; + } + ScopedWriteLock sl (lock); if (pimpl != nullptr) { - pimpl->stopReadOperation = true; - const char buffer[] { 0 }; const auto done = ::write (pimpl->pipeIn.get(), buffer, numElementsInArray (buffer)); ignoreUnused (done); From 2dbff9175f998bb4d51abf08c27da3c6f5ca154c Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Mon, 7 Mar 2022 19:05:08 -0800 Subject: [PATCH 22/36] Revert "NamedPipe: Fixed a deadlock on close" This reverts commit ea14d28bc9c6126da9fdc7663cebbc67a2dba739. --- modules/juce_core/native/juce_posix_NamedPipe.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/juce_core/native/juce_posix_NamedPipe.cpp b/modules/juce_core/native/juce_posix_NamedPipe.cpp index 2a0de7b8de4a..0e6e678324d6 100644 --- a/modules/juce_core/native/juce_posix_NamedPipe.cpp +++ b/modules/juce_core/native/juce_posix_NamedPipe.cpp @@ -246,17 +246,12 @@ class NamedPipe::Pimpl void NamedPipe::close() { - { - ScopedReadLock sl (lock); - - if (pimpl != nullptr) - pimpl->stopReadOperation = true; - } - ScopedWriteLock sl (lock); if (pimpl != nullptr) { + pimpl->stopReadOperation = true; + const char buffer[] { 0 }; const auto done = ::write (pimpl->pipeIn.get(), buffer, numElementsInArray (buffer)); ignoreUnused (done); From 25bb723354e3261fb26f811837b2aa83f95f1bee Mon Sep 17 00:00:00 2001 From: David Rowland Date: Mon, 21 Mar 2022 14:46:42 +0000 Subject: [PATCH 23/36] Tracktion: Fixed an issue where the coordinator process wouldn't send pings and kill the worker process --- modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp b/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp index 3623c064c563..3ad479f2cfaf 100644 --- a/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp +++ b/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp @@ -169,6 +169,7 @@ bool ChildProcessCoordinator::launchWorkerProcess (const File& executable, const if (connection->isConnected()) { + connection->startPinging(); sendMessageToWorker ({ startMessage, specialMessageSize }); return true; } From 5588ad4b3c736b98d8269bf484354114add6ac4b Mon Sep 17 00:00:00 2001 From: David Rowland Date: Mon, 21 Mar 2022 16:42:34 +0000 Subject: [PATCH 24/36] Tracktion: Added a SetForegroundWindow call to toFrontCallback1which should fix windows dropping to back --- modules/juce_gui_basics/native/juce_win32_Windowing.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 4ffc09d9a8e3..03f6a85c1085 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -2447,6 +2447,7 @@ class HWNDComponentPeer : public ComponentPeer, static void* toFrontCallback1 (void* h) { BringWindowToTop ((HWND) h); + SetForegroundWindow ((HWND) h); return nullptr; } From bc1c2156717557835dbcaab7ea8982e938cfdac2 Mon Sep 17 00:00:00 2001 From: Oli Date: Tue, 22 Mar 2022 11:52:15 +0000 Subject: [PATCH 25/36] DirectoryContentsList: Fix a data race Fix improper use of non-atomic pointer validity to report state of background search thread state --- .../filebrowser/juce_DirectoryContentsList.cpp | 11 ++++++----- .../filebrowser/juce_DirectoryContentsList.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp index 6976073e85d7..07aef35519e3 100644 --- a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp @@ -66,10 +66,10 @@ void DirectoryContentsList::setDirectory (const File& directory, auto newFlags = fileTypeFlags; - if (includeDirectories) newFlags |= File::findDirectories; + if (includeDirectories) newFlags |= File::findDirectories; else newFlags &= ~File::findDirectories; - if (includeFiles) newFlags |= File::findFiles; + if (includeFiles) newFlags |= File::findFiles; else newFlags &= ~File::findFiles; setTypeFlags (newFlags); @@ -88,7 +88,7 @@ void DirectoryContentsList::stopSearching() { shouldStop = true; thread.removeTimeSliceClient (this); - fileFindHandle = nullptr; + isSearching = false; } void DirectoryContentsList::clear() @@ -110,8 +110,9 @@ void DirectoryContentsList::refresh() if (root.isDirectory()) { - fileFindHandle = std::make_unique (root, false, "*", fileTypeFlags); + fileFindHandle = std::make_unique(root, false, "*", fileTypeFlags); shouldStop = false; + isSearching = true; thread.addTimeSliceClient (this); } } @@ -165,7 +166,7 @@ bool DirectoryContentsList::contains (const File& targetFile) const bool DirectoryContentsList::isStillLoading() const { - return fileFindHandle != nullptr; + return isSearching; } void DirectoryContentsList::changed() diff --git a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h index 691155aead6c..a04655458452 100644 --- a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h +++ b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h @@ -209,6 +209,7 @@ class JUCE_API DirectoryContentsList : public ChangeBroadcaster, std::unique_ptr fileFindHandle; std::atomic shouldStop { true }; + bool isSearching = false; bool wasEmpty = true; From c3a32bdb78fcccfabe43066a2ba8f5ad5ae75c8a Mon Sep 17 00:00:00 2001 From: Oli Date: Tue, 22 Mar 2022 11:52:47 +0000 Subject: [PATCH 26/36] AudioProcessorGraph: Fix MIDI channel bug and graph execution modification MIDI only plugins are no longer provided valid audio buffers Graph nodes are only executed when they have active connections --- examples/Plugins/ArpeggiatorPluginDemo.h | 2 +- .../processors/juce_AudioProcessorGraph.cpp | 11 ++++++++++- .../processors/juce_AudioProcessorGraph.h | 10 ++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/examples/Plugins/ArpeggiatorPluginDemo.h b/examples/Plugins/ArpeggiatorPluginDemo.h index 803630f1b1ea..bcf6006d9a49 100644 --- a/examples/Plugins/ArpeggiatorPluginDemo.h +++ b/examples/Plugins/ArpeggiatorPluginDemo.h @@ -79,7 +79,7 @@ class Arpeggiator : public AudioProcessor void processBlock (AudioBuffer& buffer, MidiBuffer& midi) override { - // the audio buffer in a midi effect will have zero channels! + // A pure MIDI plugin shouldn't be provided any audio data jassert (buffer.getNumChannels() == 0); // however we use the buffer to get timing information diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index f9999c802877..bb408942d6d4 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -268,7 +268,16 @@ struct GraphRenderSequence for (int i = 0; i < totalChans; ++i) audioChannels[i] = c.audioBuffers[audioChannelsToUse.getUnchecked (i)]; - AudioBuffer buffer (audioChannels, totalChans, c.numSamples); + auto numAudioChannels = [this] + { + if (const auto* proc = node->getProcessor()) + if (proc->getTotalNumInputChannels() == 0 && proc->getTotalNumOutputChannels() == 0) + return 0; + + return totalChans; + }(); + + AudioBuffer buffer (audioChannels, numAudioChannels, c.numSamples); if (processor.isSuspended()) buffer.clear(); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index 7b6ab003a3ca..24cb4c1864a2 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -155,17 +155,27 @@ class JUCE_API AudioProcessorGraph : public AudioProcessor, void prepare (double newSampleRate, int newBlockSize, AudioProcessorGraph*, ProcessingPrecision); void unprepare(); + bool hasNoConnections() const noexcept { return inputs.isEmpty() && outputs.isEmpty(); } + template void processBlock (AudioBuffer& audio, MidiBuffer& midi) { + if (hasNoConnections()) + return; + const ScopedLock lock (processorLock); + processor->processBlock (audio, midi); } template void processBlockBypassed (AudioBuffer& audio, MidiBuffer& midi) { + if (hasNoConnections()) + return; + const ScopedLock lock (processorLock); + processor->processBlockBypassed (audio, midi); } From f654b49112383ca66c5dd43b1525226401adb84e Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Fri, 1 Apr 2022 10:04:05 -0700 Subject: [PATCH 27/36] Put Windows zordering back the way it was --- modules/juce_gui_basics/native/juce_win32_Windowing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 4ffc09d9a8e3..6a90dda4316c 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -2446,7 +2446,7 @@ class HWNDComponentPeer : public ComponentPeer, static void* toFrontCallback1 (void* h) { - BringWindowToTop ((HWND) h); + SetForegroundWindow ((HWND) h); return nullptr; } From 5c0345ada984fb40c24486b39a8834b1a34061f6 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Tue, 27 Sep 2022 10:18:36 -0700 Subject: [PATCH 28/36] tracktion: juce 7 fixes --- modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h | 2 +- modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp | 2 +- modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm | 2 +- modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h b/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h index d616a33b47ff..8f2277cf1757 100644 --- a/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h +++ b/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h @@ -68,7 +68,7 @@ class JUCE_API AudioCDReader : public AudioFormatReader ~AudioCDReader() override; /** Implementation of the AudioFormatReader method. */ - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, + bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override; /** Checks whether the CD has been removed from the drive. */ diff --git a/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp b/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp index a653858d80c1..739b81bb4d78 100644 --- a/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp +++ b/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp @@ -50,7 +50,7 @@ void AudioCDReader::refreshTrackLengths() { } -bool AudioCDReader::readSamples (int**, int, int, +bool AudioCDReader::readSamples (int* const*, int, int, int64, int) { return false; diff --git a/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm b/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm index 9b5ee4e64462..381c98fc04c7 100644 --- a/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm +++ b/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm @@ -178,7 +178,7 @@ static int compareElements (const File& first, const File& second) } } -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, +bool AudioCDReader::readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) { while (numSamples > 0) diff --git a/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp b/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp index f1e00439e068..69fb26f50c12 100644 --- a/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp +++ b/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp @@ -1035,7 +1035,7 @@ AudioCDReader::~AudioCDReader() delete device; } -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, +bool AudioCDReader::readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) { using namespace CDReaderHelpers; From 3d4742a739d89438f39cafa3d2c1015c5a23e0cc Mon Sep 17 00:00:00 2001 From: David Rowland Date: Fri, 7 Oct 2022 13:09:08 +0100 Subject: [PATCH 29/36] Tracktion: Reverted custom CoreAudio latency calculation --- .../native/juce_mac_CoreAudio.cpp | 88 ++++++++++++------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index e433dc0c3336..802bd9342397 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -280,17 +280,6 @@ bool JUCE_CALLTYPE SystemAudioVolume::setGain (float gain) { return SystemVol bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { return SystemVol (kAudioDevicePropertyMute).isMuted(); } bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool mute) { return SystemVol (kAudioDevicePropertyMute).setMuted (mute); } -static double machToSeconds (UInt64 machTime) -{ - const int64_t kNanoPerS = 1000 * 1000 * 1000; - static mach_timebase_info_data_t s_timebase_info; - - if (s_timebase_info.denom == 0) - mach_timebase_info (&s_timebase_info); - - return ((machTime * s_timebase_info.numer) / double (kNanoPerS * s_timebase_info.denom)); -} - //============================================================================== struct CoreAudioClasses { @@ -746,15 +735,6 @@ class CoreAudioInternal : private Timer, double getSampleRate() const { return sampleRate; } int getBufferSize() const { return bufferSize; } - void updateLatency (double now, double inputTimestamp, double outputTimestamp) - { - const auto inputLatencyTime = now - inputTimestamp; - const auto outputLatencyTime = outputTimestamp - now; - - inputLatency.store (roundToInt (inputLatencyTime * sampleRate), std::memory_order_relaxed); - outputLatency.store (roundToInt (outputLatencyTime * sampleRate), std::memory_order_relaxed); - } - void audioCallback (const AudioTimeStamp* inputTimestamp, const AudioTimeStamp* outputTimestamp, const AudioBufferList* inInputData, @@ -1035,8 +1015,6 @@ class CoreAudioInternal : private Timer, static constexpr Float64 invalidSampleTime = std::numeric_limits::max(); CoreAudioIODevice& owner; - std::atomic inputLatency { 0 }; - std::atomic outputLatency { 0 }; int bitDepth = 32; int xruns = 0; Array sampleRates; @@ -1128,17 +1106,6 @@ class CoreAudioInternal : private Timer, const AudioTimeStamp* inOutputTime, void* device) { - auto internal = static_cast (device); - - if (inNow->mFlags & kAudioTimeStampHostTimeValid - && inInputTime->mFlags & kAudioTimeStampHostTimeValid - && inOutputTime->mFlags & kAudioTimeStampHostTimeValid) - { - internal->updateLatency (machToSeconds (inNow->mHostTime), - machToSeconds (inInputTime->mHostTime), - machToSeconds (inOutputTime->mHostTime)); - } - static_cast (device)->audioCallback (inInputTime, inOutputTime, inInputData, outOutputData); return noErr; } @@ -2294,4 +2261,59 @@ class CoreAudioIODeviceType : public AudioIODeviceType, #undef JUCE_COREAUDIOLOG +} // namespace juce if (out == nullptr) return in.release(); + + auto combo = std::make_unique (combinedName, this, std::move (in), std::move (out)); + return combo.release(); + } + + void audioDeviceListChanged() + { + scanForDevices(); + callDeviceChangeListeners(); + } + + //============================================================================== +private: + StringArray inputDeviceNames, outputDeviceNames; + Array inputIds, outputIds; + + bool hasScanned = false; + + void handleAsyncUpdate() override + { + audioDeviceListChanged(); + } + + static int getNumChannels (AudioDeviceID deviceID, bool input) + { + int total = 0; + + if (auto bufList = audioObjectGetProperty (deviceID, { kAudioDevicePropertyStreamConfiguration, + CoreAudioInternal::getScope (input), + juceAudioObjectPropertyElementMain })) + { + auto numStreams = (int) bufList->mNumberBuffers; + + for (int i = 0; i < numStreams; ++i) + total += bufList->mBuffers[i].mNumberChannels; + } + + return total; + } + + static OSStatus hardwareListenerProc (AudioDeviceID, UInt32, const AudioObjectPropertyAddress*, void* clientData) + { + static_cast (clientData)->triggerAsyncUpdate(); + return noErr; + } + + JUCE_DECLARE_WEAK_REFERENCEABLE (CoreAudioIODeviceType) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioIODeviceType) +}; + +}; + +#undef JUCE_COREAUDIOLOG + } // namespace juce From 0cf1b3e0aa92eb62e2bdff722fd44faeaad98816 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Fri, 7 Oct 2022 13:15:44 +0100 Subject: [PATCH 30/36] Tracktion: Fixed a copy/paste error in the last commit --- .../native/juce_mac_CoreAudio.cpp | 55 ------------------- 1 file changed, 55 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index 802bd9342397..0dae4caf78fb 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -2261,59 +2261,4 @@ class CoreAudioIODeviceType : public AudioIODeviceType, #undef JUCE_COREAUDIOLOG -} // namespace juce if (out == nullptr) return in.release(); - - auto combo = std::make_unique (combinedName, this, std::move (in), std::move (out)); - return combo.release(); - } - - void audioDeviceListChanged() - { - scanForDevices(); - callDeviceChangeListeners(); - } - - //============================================================================== -private: - StringArray inputDeviceNames, outputDeviceNames; - Array inputIds, outputIds; - - bool hasScanned = false; - - void handleAsyncUpdate() override - { - audioDeviceListChanged(); - } - - static int getNumChannels (AudioDeviceID deviceID, bool input) - { - int total = 0; - - if (auto bufList = audioObjectGetProperty (deviceID, { kAudioDevicePropertyStreamConfiguration, - CoreAudioInternal::getScope (input), - juceAudioObjectPropertyElementMain })) - { - auto numStreams = (int) bufList->mNumberBuffers; - - for (int i = 0; i < numStreams; ++i) - total += bufList->mBuffers[i].mNumberChannels; - } - - return total; - } - - static OSStatus hardwareListenerProc (AudioDeviceID, UInt32, const AudioObjectPropertyAddress*, void* clientData) - { - static_cast (clientData)->triggerAsyncUpdate(); - return noErr; - } - - JUCE_DECLARE_WEAK_REFERENCEABLE (CoreAudioIODeviceType) - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioIODeviceType) -}; - -}; - -#undef JUCE_COREAUDIOLOG - } // namespace juce From 342288b960e37b76109103a65c3ca791b19a84fe Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Sat, 14 Jan 2023 16:02:04 -0800 Subject: [PATCH 31/36] tracktion: add SafePointer == operator --- modules/juce_gui_basics/components/juce_Component.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index 9f7304969532..a380b44728de 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -2313,6 +2313,9 @@ class JUCE_API Component : public MouseListener /** If the component is valid, this deletes it and sets this pointer to null. */ void deleteAndZero() { delete getComponent(); } + bool operator== (const SafePointer& component) const noexcept { return weakRef == component; } + bool operator!= (const SafePointer& component) const noexcept { return weakRef != component; } + bool operator== (ComponentType* component) const noexcept { return weakRef == component; } bool operator!= (ComponentType* component) const noexcept { return weakRef != component; } From afb5e05a4f0188b4fd60a23e1da0daa0469e97e4 Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Thu, 23 Feb 2023 09:04:05 -0800 Subject: [PATCH 32/36] Use checkout v3 --- .github/workflows/merge_upstream.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/merge_upstream.yaml b/.github/workflows/merge_upstream.yaml index 2c94348ffcf1..b6763eeab8cc 100644 --- a/.github/workflows/merge_upstream.yaml +++ b/.github/workflows/merge_upstream.yaml @@ -10,7 +10,7 @@ jobs: name: Merge Upstream runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: token: ${{ secrets.TOKEN }} - run: | From 92ea22b06178a0151f99a12e0163dec3042ebe5c Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Tue, 14 Mar 2023 15:21:32 -0700 Subject: [PATCH 33/36] tracktion: fix bad merge --- .../juce_audio_plugin_client_VST2.cpp | 17 +++++++++++++ .../juce_audio_plugin_client_VST3.cpp | 24 +++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp index 487b356b6f2a..7504c106d2da 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp @@ -917,6 +917,7 @@ class JuceVSTWrapper : public AudioProcessorListener, case Vst2::effGetNumMidiInputChannels: return handleGetNumMidiInputChannels(); case Vst2::effGetNumMidiOutputChannels: return handleGetNumMidiOutputChannels(); case Vst2::effEditIdle: return handleEditIdle(); + case Vst2::effGetMidiKeyName: return handleGetMidiKeyName (args); default: return 0; } } @@ -2051,6 +2052,22 @@ class JuceVSTWrapper : public AudioProcessorListener, return 0; } + pointer_sized_int handleGetMidiKeyName (VstOpCodeArguments args) + { + if (processor != nullptr) + { + String name; + Vst2::MidiKeyName* keyName = (Vst2::MidiKeyName*)args.ptr; + + if (processor->hasNameForMidiNoteNumber (keyName->thisKeyNumber, args.index, name)) + { + name.copyToUTF8 (keyName->keyName, sizeof (keyName->keyName)); + return 1; + } + } + return 0; + } + //============================================================================== ScopedJuceInitialiser_GUI libraryInitialiser; diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp index 9e19247d9715..68da07852335 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp @@ -484,9 +484,29 @@ class JuceAudioProcessor : public Vst::IUnitInfo return kResultFalse; } + tresult PLUGIN_API hasProgramPitchNames (Vst::ProgramListID, Steinberg::int32) override + { + String name; + for (int i = 0; i < 127; i++) + if (audioProcessor->hasNameForMidiNoteNumber (i, 1, name) == kResultTrue) + return kResultTrue; + + return kResultFalse; + } + + tresult PLUGIN_API getProgramPitchName (Vst::ProgramListID, Steinberg::int32, Steinberg::int16 midiNote, Vst::String128 name) override + { + String nameOut; + if (audioProcessor->hasNameForMidiNoteNumber (midiNote, 1, nameOut)) + { + toString128 (name, nameOut); + return kResultTrue; + } + + return kResultFalse; + } + tresult PLUGIN_API getProgramInfo (Vst::ProgramListID, Steinberg::int32, Vst::CString, Vst::String128) override { return kNotImplemented; } - tresult PLUGIN_API hasProgramPitchNames (Vst::ProgramListID, Steinberg::int32) override { return kNotImplemented; } - tresult PLUGIN_API getProgramPitchName (Vst::ProgramListID, Steinberg::int32, Steinberg::int16, Vst::String128) override { return kNotImplemented; } tresult PLUGIN_API selectUnit (Vst::UnitID) override { return kNotImplemented; } tresult PLUGIN_API setUnitProgramData (Steinberg::int32, Steinberg::int32, IBStream*) override { return kNotImplemented; } Vst::UnitID PLUGIN_API getSelectedUnit() override { return Vst::kRootUnitId; } From f639c83c9a48df202e82e6542fbbdc2fb0f4a068 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Wed, 17 May 2023 20:45:37 +0100 Subject: [PATCH 34/36] TableListBox: Fixed an issue with the "Table" part of the list box being sliced off resulting in the wrong virtual functions being called --- modules/juce_gui_basics/widgets/juce_TableListBox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_basics/widgets/juce_TableListBox.cpp b/modules/juce_gui_basics/widgets/juce_TableListBox.cpp index 61e1bcd4d855..aa81bea0c469 100644 --- a/modules/juce_gui_basics/widgets/juce_TableListBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_TableListBox.cpp @@ -219,7 +219,7 @@ class TableListBox::RowComp : public TooltipClient, return std::make_unique (*this); } - ListBox& getOwner() const { return owner; } + TableListBox& getOwner() const { return owner; } private: //============================================================================== From 6518c3ee1262d1c06ac90901dab2a62a3cc8321d Mon Sep 17 00:00:00 2001 From: Roland Rabien Date: Sat, 7 Oct 2023 08:51:14 -0700 Subject: [PATCH 35/36] tracktion: fix plugin hosting on Sonoma --- modules/juce_audio_processors/juce_audio_processors.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 27ed7c32907d..704db905866a 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -166,6 +166,10 @@ struct NSViewComponentWithParent : public NSViewComponent, addMethod (@selector (isOpaque), isOpaque); addMethod (@selector (didAddSubview:), didAddSubview); + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") + addMethod (@selector (clipsToBounds), [] (id, SEL) { return YES; }); + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + registerClass(); } From ee4665682cbd1b231b95075974a94404b61936e2 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Tue, 5 Dec 2023 23:11:17 +0000 Subject: [PATCH 36/36] Add missing parameters in AlertWindow::showOkCancelBox --- .../juce_audio_processors/scanning/juce_PluginListComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index f4b5da87aaaa..7478906103b9 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -302,7 +302,7 @@ PopupMenu PluginListComponent::createOptionsMenu() { auto title = "Remove all " + format->getName() + " plugins?"; auto message = "Are you sure you want to remove all " + format->getName() + " plugins?"; - if (AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, title, message, TRANS("Yes"), TRANS("No"))) + if (AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, title, message, TRANS("Yes"), TRANS("No"), nullptr, nullptr)) for (auto& pd : list.getTypesForFormat (*format)) list.removeType (pd); }));