Browse Source

Update to latest juce

Signed-off-by: falkTX <falktx@falktx.com>
tags/2021-03-15
falkTX 1 year ago
parent
commit
2d1d8fa5d2
25 changed files with 966 additions and 675 deletions
  1. +2
    -0
      libs/juce-current/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp
  2. +12
    -0
      libs/juce-current/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h
  3. +166
    -5
      libs/juce-current/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp
  4. +13
    -0
      libs/juce-current/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm
  5. +4
    -0
      libs/juce-current/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
  6. +6
    -4
      libs/juce-current/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp
  7. +0
    -1
      libs/juce-current/source/modules/juce_audio_plugin_client/juce_audio_plugin_client.h
  8. +0
    -439
      libs/juce-current/source/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h
  9. +0
    -67
      libs/juce-current/source/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp
  10. +41
    -51
      libs/juce-current/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
  11. +56
    -50
      libs/juce-current/source/modules/juce_audio_processors/format_types/juce_VST3Common.h
  12. +1
    -0
      libs/juce-current/source/modules/juce_audio_processors/juce_audio_processors.cpp
  13. +1
    -0
      libs/juce-current/source/modules/juce_audio_processors/juce_audio_processors.h
  14. +309
    -0
      libs/juce-current/source/modules/juce_audio_processors/utilities/juce_PluginHostType.cpp
  15. +242
    -0
      libs/juce-current/source/modules/juce_audio_processors/utilities/juce_PluginHostType.h
  16. +2
    -0
      libs/juce-current/source/modules/juce_dsp/frequency/juce_Convolution.cpp
  17. +5
    -2
      libs/juce-current/source/modules/juce_dsp/frequency/juce_Convolution_test.cpp
  18. +1
    -0
      libs/juce-current/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp
  19. +38
    -32
      libs/juce-current/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp
  20. +3
    -1
      libs/juce-current/source/modules/juce_gui_basics/menus/juce_PopupMenu.h
  21. +14
    -4
      libs/juce-current/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  22. +34
    -16
      libs/juce-current/source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
  23. +2
    -2
      libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
  24. +2
    -0
      libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h
  25. +12
    -1
      libs/juce-current/source/modules/juce_opengl/native/juce_OpenGL_linux_X11.h

+ 2
- 0
libs/juce-current/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp View File

@@ -463,6 +463,8 @@ AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); }
AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); }
AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); }
AudioChannelSet AudioChannelSet::create7point0point4() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topFrontLeft) | (1u << topFrontRight) | (1u << topRearLeft) | (1u << topRearRight)); }
AudioChannelSet AudioChannelSet::create7point1point4() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topFrontLeft) | (1u << topFrontRight) | (1u << topRearLeft) | (1u << topRearRight)); }
AudioChannelSet AudioChannelSet::ambisonic (int order)
{


+ 12
- 0
libs/juce-current/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h View File

@@ -208,6 +208,18 @@ public:
*/
static AudioChannelSet JUCE_CALLTYPE create7point1point2();
/** Creates a set for Dolby Atmos 7.0.4 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight).
Is equivalent to: n/a (VST), n/a (AAX), n/a (CoreAudio)
*/
static AudioChannelSet JUCE_CALLTYPE create7point0point4();
/** Creates a set for Dolby Atmos 7.1.4 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE, topFrontLeft, topFrontRight, topRearLeft, topRearRight).
Is equivalent to: k71_4 (VST), n/a (AAX), n/a (CoreAudio)
*/
static AudioChannelSet JUCE_CALLTYPE create7point1point4();
//==============================================================================
/** Creates a set for quadraphonic surround setup (left, right, leftSurround, rightSurround)


+ 166
- 5
libs/juce-current/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp View File

@@ -44,13 +44,20 @@ void MemoryAudioSource::releaseResources() {}
void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
if (buffer.getNumSamples() == 0)
{
bufferToFill.clearActiveBufferRegion();
return;
}
auto& dst = *bufferToFill.buffer;
auto channels = jmin (dst.getNumChannels(), buffer.getNumChannels());
auto max = 0, pos = 0;
auto n = buffer.getNumSamples(), m = bufferToFill.numSamples;
int max = 0, pos = 0;
auto n = buffer.getNumSamples();
auto m = bufferToFill.numSamples;
int i;
for (i = position; (i < n || isCurrentlyLooping) && (pos < m); i += max)
int i = position;
for (; (i < n || isCurrentlyLooping) && (pos < m); i += max)
{
max = jmin (m - pos, n - (i % n));
@@ -67,7 +74,7 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT
if (pos < m)
dst.clear (bufferToFill.startSample + pos, m - pos);
position = (i % n);
position = i;
}
//==============================================================================
@@ -97,4 +104,158 @@ void MemoryAudioSource::setLooping (bool shouldLoop)
isCurrentlyLooping = shouldLoop;
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
static bool operator== (const AudioBuffer<float>& a, const AudioBuffer<float>& b)
{
if (a.getNumChannels() != b.getNumChannels())
return false;
for (int channel = 0; channel < a.getNumChannels(); ++channel)
{
auto* aPtr = a.getReadPointer (channel);
auto* bPtr = b.getReadPointer (channel);
if (std::vector<float> (aPtr, aPtr + a.getNumSamples())
!= std::vector<float> (bPtr, bPtr + b.getNumSamples()))
{
return false;
}
}
return true;
}
struct MemoryAudioSourceTests : public UnitTest
{
MemoryAudioSourceTests() : UnitTest ("MemoryAudioSource", UnitTestCategories::audio) {}
void runTest() override
{
constexpr int blockSize = 512;
AudioBuffer<float> bufferToFill { 2, blockSize };
AudioSourceChannelInfo channelInfo { bufferToFill };
beginTest ("A zero-length buffer produces silence, whether or not looping is enabled");
{
for (const bool enableLooping : { false, true })
{
AudioBuffer<float> buffer;
MemoryAudioSource source { buffer, true, false };
source.setLooping (enableLooping);
source.prepareToPlay (blockSize, 44100.0);
for (int i = 0; i < 2; ++i)
{
play (source, channelInfo);
expect (isSilent (bufferToFill));
}
}
}
beginTest ("A short buffer without looping is played once and followed by silence");
{
auto buffer = getShortBuffer();
MemoryAudioSource source { buffer, true, false };
source.setLooping (false);
source.prepareToPlay (blockSize, 44100.0);
play (source, channelInfo);
auto copy = buffer;
copy.setSize (buffer.getNumChannels(), blockSize, true, true, false);
expect (bufferToFill == copy);
play (source, channelInfo);
expect (isSilent (bufferToFill));
}
beginTest ("A short buffer with looping is played multiple times");
{
auto buffer = getShortBuffer();
MemoryAudioSource source { buffer, true, false };
source.setLooping (true);
source.prepareToPlay (blockSize, 44100.0);
play (source, channelInfo);
for (int sample = 0; sample < buffer.getNumSamples(); ++sample)
expect (bufferToFill.getSample (0, sample + buffer.getNumSamples()) == buffer.getSample (0, sample));
expect (! isSilent (bufferToFill));
}
beginTest ("A long buffer without looping is played once");
{
auto buffer = getLongBuffer();
MemoryAudioSource source { buffer, true, false };
source.setLooping (false);
source.prepareToPlay (blockSize, 44100.0);
play (source, channelInfo);
auto copy = buffer;
copy.setSize (buffer.getNumChannels(), blockSize, true, true, false);
expect (bufferToFill == copy);
for (int i = 0; i < 10; ++i)
play (source, channelInfo);
expect (isSilent (bufferToFill));
}
beginTest ("A long buffer with looping is played multiple times");
{
auto buffer = getLongBuffer();
MemoryAudioSource source { buffer, true, false };
source.setLooping (true);
source.prepareToPlay (blockSize, 44100.0);
for (int i = 0; i < 100; ++i)
{
play (source, channelInfo);
expect (bufferToFill.getSample (0, 0) == buffer.getSample (0, (i * blockSize) % buffer.getNumSamples()));
}
}
}
static AudioBuffer<float> getTestBuffer (int length)
{
AudioBuffer<float> buffer { 2, length };
for (int channel = 0; channel < buffer.getNumChannels(); ++channel)
for (int sample = 0; sample < buffer.getNumSamples(); ++sample)
buffer.setSample (channel, sample, jmap ((float) sample, 0.0f, (float) length, -1.0f, 1.0f));
return buffer;
}
static AudioBuffer<float> getShortBuffer() { return getTestBuffer (5); }
static AudioBuffer<float> getLongBuffer() { return getTestBuffer (1000); }
static void play (MemoryAudioSource& source, AudioSourceChannelInfo& info)
{
info.clearActiveBufferRegion();
source.getNextAudioBlock (info);
}
static bool isSilent (const AudioBuffer<float>& b)
{
for (int channel = 0; channel < b.getNumChannels(); ++channel)
if (b.findMinMax (channel, 0, b.getNumSamples()) != Range<float>{})
return false;
return true;
}
};
static MemoryAudioSourceTests memoryAudioSourceTests;
#endif
} // namespace juce

+ 13
- 0
libs/juce-current/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm View File

@@ -675,6 +675,19 @@ public:
return noErr;
}
#if defined (MAC_OS_X_VERSION_10_12)
case kAudioUnitProperty_AUHostIdentifier:
{
if (inDataSize < sizeof (AUHostVersionIdentifier))
return kAudioUnitErr_InvalidPropertyValue;
const auto* identifier = static_cast<const AUHostVersionIdentifier*> (inData);
PluginHostType::hostIdReportedByWrapper = String::fromCFString (identifier->hostName);
return noErr;
}
#endif
default: break;
}
}


+ 4
- 0
libs/juce-current/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -612,6 +612,10 @@ public:
{
centreWithSize (getWidth(), getHeight());
}
if (auto* processor = getAudioProcessor())
if (auto* editor = processor->getActiveEditor())
setResizable (editor->isResizable(), false);
#endif
}


+ 6
- 4
libs/juce-current/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp View File

@@ -927,11 +927,13 @@ public:
{
if (auto* pluginInstance = getPluginInstance())
{
if (pluginInstance->hasEditor() && name != nullptr
&& strcmp (name, Vst::ViewType::kEditor) == 0)
{
const auto mayCreateEditor = pluginInstance->hasEditor()
&& name != nullptr
&& std::strcmp (name, Vst::ViewType::kEditor) == 0
&& pluginInstance->getActiveEditor() == nullptr;
if (mayCreateEditor)
return new JuceVST3Editor (*this, *pluginInstance);
}
}
return nullptr;


+ 0
- 1
libs/juce-current/source/modules/juce_audio_plugin_client/juce_audio_plugin_client.h View File

@@ -126,6 +126,5 @@
#define JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE (JUCE_IOS || JUCE_ANDROID)
#endif
#include "utility/juce_PluginHostType.h"
#include "utility/juce_CreatePluginFilter.h"
#include "VST/juce_VSTCallbackHandler.h"

+ 0
- 439
libs/juce-current/source/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h View File

@@ -1,439 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
A useful utility class to determine the host or DAW in which your plugin is
loaded.
Declare a PluginHostType object in your class to use it.
@tags{Audio}
*/
class PluginHostType
{
public:
//==============================================================================
PluginHostType() : type (getHostType()) {}
PluginHostType (const PluginHostType& other) = default;
PluginHostType& operator= (const PluginHostType& other) = default;
//==============================================================================
/** Represents the host type and also its version for some hosts. */
enum HostType
{
UnknownHost, /**< Represents an unknown host. */
AbletonLive6, /**< Represents Ableton Live 6. */
AbletonLive7, /**< Represents Ableton Live 7. */
AbletonLive8, /**< Represents Ableton Live 8. */
AbletonLive9, /**< Represents Ableton Live 9. */
AbletonLive10, /**< Represents Ableton Live 10. */
AbletonLiveGeneric, /**< Represents Ableton Live. */
AdobeAudition, /**< Represents Adobe Audition. */
AdobePremierePro, /**< Represents Adobe Premiere Pro. */
AppleGarageBand, /**< Represents Apple GarageBand. */
AppleLogic, /**< Represents Apple Logic Pro. */
AppleMainStage, /**< Represents Apple Main Stage. */
Ardour, /**< Represents Ardour. */
AvidProTools, /**< Represents Avid Pro Tools. */
BitwigStudio, /**< Represents Bitwig Studio. */
CakewalkSonar8, /**< Represents Cakewalk Sonar 8. */
CakewalkSonarGeneric, /**< Represents Cakewalk Sonar. */
CakewalkByBandlab, /**< Represents Cakewalk by Bandlab. */
DaVinciResolve, /**< Represents DaVinci Resolve. */
DigitalPerformer, /**< Represents Digital Performer. */
FinalCut, /**< Represents Apple Final Cut Pro. */
FruityLoops, /**< Represents Fruity Loops. */
JUCEPluginHost, /**< Represents the JUCE AudioPluginHost */
MagixSamplitude, /**< Represents Magix Samplitude. */
MagixSequoia, /**< Represents Magix Sequoia. */
MergingPyramix, /**< Represents Merging Pyramix. */
MuseReceptorGeneric, /**< Represents Muse Receptor. */
pluginval, /**< Represents pluginval. */
Reaper, /**< Represents Cockos Reaper. */
Reason, /**< Represents Reason. */
Renoise, /**< Represents Renoise. */
SADiE, /**< Represents SADiE. */
SteinbergCubase4, /**< Represents Steinberg Cubase 4. */
SteinbergCubase5, /**< Represents Steinberg Cubase 5. */
SteinbergCubase5Bridged, /**< Represents Steinberg Cubase 5 Bridged. */
SteinbergCubase6, /**< Represents Steinberg Cubase 6. */
SteinbergCubase7, /**< Represents Steinberg Cubase 7. */
SteinbergCubase8, /**< Represents Steinberg Cubase 8. */
SteinbergCubase8_5, /**< Represents Steinberg Cubase 8.5. */
SteinbergCubase9, /**< Represents Steinberg Cubase 9. */
SteinbergCubase9_5, /**< Represents Steinberg Cubase 9.5. */
SteinbergCubase10, /**< Represents Steinberg Cubase 10. */
SteinbergCubase10_5, /**< Represents Steinberg Cubase 10.5. */
SteinbergCubaseGeneric, /**< Represents Steinberg Cubase. */
SteinbergNuendo3, /**< Represents Steinberg Nuendo 3. */
SteinbergNuendo4, /**< Represents Steinberg Nuendo 4. */
SteinbergNuendo5, /**< Represents Steinberg Nuendo 5. */
SteinbergNuendoGeneric, /**< Represents Steinberg Nuendo. */
SteinbergWavelab5, /**< Represents Steinberg Wavelab 5. */
SteinbergWavelab6, /**< Represents Steinberg Wavelab 6. */
SteinbergWavelab7, /**< Represents Steinberg Wavelab 7. */
SteinbergWavelab8, /**< Represents Steinberg Wavelab 8. */
SteinbergWavelabGeneric, /**< Represents Steinberg Wavelab. */
SteinbergTestHost, /**< Represents Steinberg's VST3 Test Host. */
StudioOne, /**< Represents PreSonus Studio One. */
Tracktion3, /**< Represents Tracktion 3. */
TracktionGeneric, /**< Represents Tracktion. */
TracktionWaveform, /**< Represents Tracktion Waveform. */
VBVSTScanner, /**< Represents VB Audio VST Scanner. */
ViennaEnsemblePro, /**< Represents Vienna Ensemble Pro. */
WaveBurner /**< Represents Apple WaveBurner. */
};
HostType type;
//==============================================================================
/** Returns true if the host is any version of Ableton Live. */
bool isAbletonLive() const noexcept { return type == AbletonLive6 || type == AbletonLive7 || type == AbletonLive8
|| type == AbletonLive9 || type == AbletonLive10 || type == AbletonLiveGeneric; }
/** Returns true if the host is Adobe Audition. */
bool isAdobeAudition() const noexcept { return type == AdobeAudition; }
/** Returns true if the host is Ardour. */
bool isArdour() const noexcept { return type == Ardour; }
/** Returns true if the host is Bitwig Studio. */
bool isBitwigStudio() const noexcept { return type == BitwigStudio; }
/** Returns true if the host is any version of Steinberg Cubase. */
bool isCubase() const noexcept { return type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase5Bridged || type == SteinbergCubase6
|| type == SteinbergCubase7 || type == SteinbergCubase8 || type == SteinbergCubase8_5 || type == SteinbergCubase9
|| type == SteinbergCubase9_5 || type == SteinbergCubase10 || type == SteinbergCubase10_5 || type == SteinbergCubaseGeneric; }
/** Returns true if the host is Steinberg Cubase 7 or later. */
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); }
/** Returns true if the host is Steinberg Cubase 5 Bridged. */
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; }
/** Returns true if the host is DaVinci Resolve. */
bool isDaVinciResolve() const noexcept { return type == DaVinciResolve; }
/** Returns true if the host is Digital Performer. */
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
/** Returns true if the host is Apple Final Cut Pro. */
bool isFinalCut() const noexcept { return type == FinalCut; }
/** Returns true if the host is Fruity Loops. */
bool isFruityLoops() const noexcept { return type == FruityLoops; }
/** Returns true if the host is Apple GarageBand. */
bool isGarageBand() const noexcept { return type == AppleGarageBand; }
/** Returns true if the host is the JUCE AudioPluginHost */
bool isJUCEPluginHost() const noexcept { return type == JUCEPluginHost; }
/** Returns true if the host is Apple Logic Pro. */
bool isLogic() const noexcept { return type == AppleLogic; }
/** Returns true if the host is Apple MainStage. */
bool isMainStage() const noexcept { return type == AppleMainStage; }
/** Returns true if the host is any version of Steinberg Nuendo. */
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; }
/** Returns true if the host is pluginval. */
bool isPluginval() const noexcept { return type == pluginval; }
/** Returns true if the host is Adobe Premiere Pro. */
bool isPremiere() const noexcept { return type == AdobePremierePro; }
/** Returns true if the host is Avid Pro Tools. */
bool isProTools() const noexcept { return type == AvidProTools; }
/** Returns true if the host is Merging Pyramix. */
bool isPyramix() const noexcept { return type == MergingPyramix; }
/** Returns true if the host is Muse Receptor. */
bool isReceptor() const noexcept { return type == MuseReceptorGeneric; }
/** Returns true if the host is Cockos Reaper. */
bool isReaper() const noexcept { return type == Reaper; }
/** Returns true if the host is Reason. */
bool isReason() const noexcept { return type == Reason; }
/** Returns true if the host is Renoise. */
bool isRenoise() const noexcept { return type == Renoise; }
/** Returns true if the host is SADiE. */
bool isSADiE() const noexcept { return type == SADiE; }
/** Returns true if the host is Magix Samplitude. */
bool isSamplitude() const noexcept { return type == MagixSamplitude; }
/** Returns true if the host is Magix Sequoia. */
bool isSequoia() const noexcept { return type == MagixSequoia; }
/** Returns true if the host is any version of Cakewalk Sonar. */
bool isSonar() const noexcept { return type == CakewalkSonar8 || type == CakewalkSonarGeneric || type == CakewalkByBandlab; }
/** Returns true if the host is Steinberg's VST3 Test Host. */
bool isSteinbergTestHost() const noexcept { return type == SteinbergTestHost; }
/** Returns true if the host is any product from Steinberg. */
bool isSteinberg() const noexcept { return isCubase() || isNuendo() || isWavelab() || isSteinbergTestHost(); }
/** Returns true if the host is PreSonus Studio One. */
bool isStudioOne() const noexcept { return type == StudioOne; }
/** Returns true if the host is any version of Tracktion. */
bool isTracktion() const noexcept { return type == Tracktion3 || type == TracktionGeneric || isTracktionWaveform(); }
/** Returns true if the host is Tracktion Waveform. */
bool isTracktionWaveform() const noexcept { return type == TracktionWaveform; }
/** Returns true if the host is VB Audio VST Scanner. */
bool isVBVSTScanner() const noexcept { return type == VBVSTScanner; }
/** Returns true if the host is Vienna Ensemble Pro. */
bool isViennaEnsemblePro() const noexcept { return type == ViennaEnsemblePro; }
/** Returns true if the host is Apple WaveBurner. */
bool isWaveBurner() const noexcept { return type == WaveBurner; }
/** Returns true if the host is any version of Steinberg WaveLab. */
bool isWavelab() const noexcept { return isWavelabLegacy() || type == SteinbergWavelab7 || type == SteinbergWavelab8 || type == SteinbergWavelabGeneric; }
/** Returns true if the host is Steinberg WaveLab 6 or below. */
bool isWavelabLegacy() const noexcept { return type == SteinbergWavelab5 || type == SteinbergWavelab6; }
//==============================================================================
/** Returns a human-readable description of the host. */
const char* getHostDescription() const noexcept
{
switch (type)
{
case AbletonLive6: return "Ableton Live 6";
case AbletonLive7: return "Ableton Live 7";
case AbletonLive8: return "Ableton Live 8";
case AbletonLive9: return "Ableton Live 9";
case AbletonLive10: return "Ableton Live 10";
case AbletonLiveGeneric: return "Ableton Live";
case AdobeAudition: return "Adobe Audition";
case AdobePremierePro: return "Adobe Premiere";
case AppleGarageBand: return "Apple GarageBand";
case AppleLogic: return "Apple Logic";
case AppleMainStage: return "Apple MainStage";
case Ardour: return "Ardour";
case AvidProTools: return "ProTools";
case BitwigStudio: return "Bitwig Studio";
case CakewalkSonar8: return "Cakewalk Sonar 8";
case CakewalkSonarGeneric: return "Cakewalk Sonar";
case CakewalkByBandlab: return "Cakewalk by Bandlab";
case DaVinciResolve: return "DaVinci Resolve";
case DigitalPerformer: return "DigitalPerformer";
case FinalCut: return "Final Cut";
case FruityLoops: return "FruityLoops";
case JUCEPluginHost: return "JUCE AudioPluginHost";
case MagixSamplitude: return "Magix Samplitude";
case MagixSequoia: return "Magix Sequoia";
case pluginval: return "pluginval";
case MergingPyramix: return "Pyramix";
case MuseReceptorGeneric: return "Muse Receptor";
case Reaper: return "Reaper";
case Reason: return "Reason";
case Renoise: return "Renoise";
case SADiE: return "SADiE";
case SteinbergCubase4: return "Steinberg Cubase 4";
case SteinbergCubase5: return "Steinberg Cubase 5";
case SteinbergCubase5Bridged: return "Steinberg Cubase 5 Bridged";
case SteinbergCubase6: return "Steinberg Cubase 6";
case SteinbergCubase7: return "Steinberg Cubase 7";
case SteinbergCubase8: return "Steinberg Cubase 8";
case SteinbergCubase8_5: return "Steinberg Cubase 8.5";
case SteinbergCubase9: return "Steinberg Cubase 9";
case SteinbergCubase9_5: return "Steinberg Cubase 9.5";
case SteinbergCubase10: return "Steinberg Cubase 10";
case SteinbergCubase10_5: return "Steinberg Cubase 10.5";
case SteinbergCubaseGeneric: return "Steinberg Cubase";
case SteinbergNuendo3: return "Steinberg Nuendo 3";
case SteinbergNuendo4: return "Steinberg Nuendo 4";
case SteinbergNuendo5: return "Steinberg Nuendo 5";
case SteinbergNuendoGeneric: return "Steinberg Nuendo";
case SteinbergWavelab5: return "Steinberg Wavelab 5";
case SteinbergWavelab6: return "Steinberg Wavelab 6";
case SteinbergWavelab7: return "Steinberg Wavelab 7";
case SteinbergWavelab8: return "Steinberg Wavelab 8";
case SteinbergWavelabGeneric: return "Steinberg Wavelab";
case SteinbergTestHost: return "Steinberg TestHost";
case StudioOne: return "Studio One";
case Tracktion3: return "Tracktion 3";
case TracktionGeneric: return "Tracktion";
case TracktionWaveform: return "Tracktion Waveform";
case VBVSTScanner: return "VBVSTScanner";
case ViennaEnsemblePro: return "Vienna Ensemble Pro";
case WaveBurner: return "WaveBurner";
case UnknownHost:
default: break;
}
return "Unknown";
}
//==============================================================================
/** Returns true if the plugin is connected with Inter-App Audio on iOS. */
bool isInterAppAudioConnected() const;
/** Switches to the host application when Inter-App Audio is used on iOS. */
void switchToHostApplication() const;
/** Gets the host app's icon when Inter-App Audio is used on iOS. */
Image getHostIcon (int size) const;
//==============================================================================
/** Returns the complete absolute path of the host application executable. */
static String getHostPath()
{
return File::getSpecialLocation (File::hostApplicationPath).getFullPathName();
}
//==============================================================================
/**
Returns the plug-in format via which the plug-in file was loaded. This value is
identical to AudioProcessor::wrapperType of the main audio processor of this
plug-in. This function is useful for code that does not have access to the
plug-in's main audio processor.
@see AudioProcessor::wrapperType
*/
static AudioProcessor::WrapperType getPluginLoadedAs() noexcept { return jucePlugInClientCurrentWrapperType; }
/** Returns true if the AudioProcessor instance is an AAX plug-in running in AudioSuite. */
static bool isInAAXAudioSuite (AudioProcessor&);
//==============================================================================
#ifndef DOXYGEN
// @internal
static AudioProcessor::WrapperType jucePlugInClientCurrentWrapperType;
static std::function<bool (AudioProcessor&)> jucePlugInIsRunningInAudioSuiteFn;
#endif
private:
static HostType getHostType()
{
auto hostPath = getHostPath();
auto hostFilename = File (hostPath).getFileName();
#if JUCE_MAC
if (hostPath.containsIgnoreCase ("Final Cut Pro.app")) return FinalCut;
if (hostPath.containsIgnoreCase ("Final Cut Pro Trial.app")) return FinalCut;
if (hostPath.containsIgnoreCase ("Live 6")) return AbletonLive6;
if (hostPath.containsIgnoreCase ("Live 7")) return AbletonLive7;
if (hostPath.containsIgnoreCase ("Live 8")) return AbletonLive8;
if (hostPath.containsIgnoreCase ("Live 9")) return AbletonLive9;
if (hostPath.containsIgnoreCase ("Live 10")) return AbletonLive10;
if (hostFilename.containsIgnoreCase ("Live")) return AbletonLiveGeneric;
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
if (hostFilename.containsIgnoreCase ("Pro Tools")) return AvidProTools;
if (hostFilename.containsIgnoreCase ("Nuendo 3")) return SteinbergNuendo3;
if (hostFilename.containsIgnoreCase ("Nuendo 4")) return SteinbergNuendo4;
if (hostFilename.containsIgnoreCase ("Nuendo 5")) return SteinbergNuendo5;
if (hostFilename.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
if (hostFilename.containsIgnoreCase ("Cubase 4")) return SteinbergCubase4;
if (hostFilename.containsIgnoreCase ("Cubase 5")) return SteinbergCubase5;
if (hostFilename.containsIgnoreCase ("Cubase 6")) return SteinbergCubase6;
if (hostFilename.containsIgnoreCase ("Cubase 7")) return SteinbergCubase7;
if (hostPath.containsIgnoreCase ("Cubase 8.app")) return SteinbergCubase8;
if (hostPath.containsIgnoreCase ("Cubase 8.5.app")) return SteinbergCubase8_5;
if (hostPath.containsIgnoreCase ("Cubase 9.app")) return SteinbergCubase9;
if (hostPath.containsIgnoreCase ("Cubase 9.5.app")) return SteinbergCubase9_5;
if (hostPath.containsIgnoreCase ("Cubase 10.app")) return SteinbergCubase10;
if (hostPath.containsIgnoreCase ("Cubase 10.5.app")) return SteinbergCubase10_5;
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
if (hostFilename.containsIgnoreCase ("WaveBurner")) return WaveBurner;
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
if (hostFilename.containsIgnoreCase ("OsxFL")) return FruityLoops;
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
#elif JUCE_WINDOWS
if (hostFilename.containsIgnoreCase ("Live 6")) return AbletonLive6;
if (hostFilename.containsIgnoreCase ("Live 7")) return AbletonLive7;
if (hostFilename.containsIgnoreCase ("Live 8")) return AbletonLive8;
if (hostFilename.containsIgnoreCase ("Live 9")) return AbletonLive9;
if (hostFilename.containsIgnoreCase ("Live 10")) return AbletonLive10;
if (hostFilename.containsIgnoreCase ("Live ")) return AbletonLiveGeneric;
if (hostFilename.containsIgnoreCase ("Audition")) return AdobeAudition;
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
if (hostFilename.containsIgnoreCase ("ProTools")) return AvidProTools;
if (hostPath.containsIgnoreCase ("SONAR 8")) return CakewalkSonar8;
if (hostFilename.containsIgnoreCase ("SONAR")) return CakewalkSonarGeneric;
if (hostFilename.containsIgnoreCase ("Cakewalk.exe")) return CakewalkByBandlab;
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
if (hostFilename.containsIgnoreCase ("Cubase4")) return SteinbergCubase4;
if (hostFilename.containsIgnoreCase ("Cubase5")) return SteinbergCubase5;
if (hostFilename.containsIgnoreCase ("Cubase6")) return SteinbergCubase6;
if (hostFilename.containsIgnoreCase ("Cubase7")) return SteinbergCubase7;
if (hostFilename.containsIgnoreCase ("Cubase8.exe")) return SteinbergCubase8;
if (hostFilename.containsIgnoreCase ("Cubase8.5.exe")) return SteinbergCubase8_5;
// Later version of Cubase scan plug-ins with a separate executable "vst2xscanner"
if (hostFilename.containsIgnoreCase ("Cubase9.5.exe")
|| hostPath.containsIgnoreCase ("Cubase 9.5")) return SteinbergCubase9_5;
if (hostFilename.containsIgnoreCase ("Cubase9.exe")
|| hostPath.containsIgnoreCase ("Cubase 9")) return SteinbergCubase9;
if (hostFilename.containsIgnoreCase ("Cubase10.5.exe")
|| hostPath.containsIgnoreCase ("Cubase 10.5")) return SteinbergCubase10_5;
if (hostFilename.containsIgnoreCase ("Cubase10.exe")
|| hostPath.containsIgnoreCase ("Cubase 10")) return SteinbergCubase10;
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
if (hostFilename.containsIgnoreCase ("VSTBridgeApp")) return SteinbergCubase5Bridged;
if (hostPath.containsIgnoreCase ("Wavelab 5")) return SteinbergWavelab5;
if (hostPath.containsIgnoreCase ("Wavelab 6")) return SteinbergWavelab6;
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
if (hostPath.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
if (hostFilename.containsIgnoreCase ("TestHost")) return SteinbergTestHost;
if (hostFilename.containsIgnoreCase ("rm-host")) return MuseReceptorGeneric;
if (hostFilename.startsWith ("FL")) return FruityLoops;
if (hostFilename.contains ("ilbridge.")) return FruityLoops;
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
if (hostFilename.containsIgnoreCase ("VST_Scanner")) return VBVSTScanner;
if (hostPath.containsIgnoreCase ("Merging Technologies")) return MergingPyramix;
if (hostFilename.startsWithIgnoreCase ("Sam")) return MagixSamplitude;
if (hostFilename.startsWithIgnoreCase ("Sequoia")) return MagixSequoia;
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
if (hostPath.containsIgnoreCase ("Bitwig Studio")) return BitwigStudio;
if (hostFilename.containsIgnoreCase ("Sadie")) return SADiE;
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
#elif JUCE_LINUX
if (hostFilename.containsIgnoreCase ("Ardour")) return Ardour;
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
#elif JUCE_IOS
#elif JUCE_ANDROID
#else
#error
#endif
return UnknownHost;
}
};
} // namespace juce

+ 0
- 67
libs/juce-current/source/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp View File

@@ -34,9 +34,6 @@
namespace juce
{
AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined;
std::function<bool (AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioSuiteFn = nullptr;
#if JucePlugin_Build_Unity
bool juce_isRunningInUnity() { return PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Unity; }
#endif
@@ -146,67 +143,3 @@ std::function<bool (AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudio
#endif
} // namespace juce
using namespace juce;
//==============================================================================
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
extern bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
extern void JUCE_CALLTYPE juce_switchToHostApplication();
extern Image JUCE_CALLTYPE juce_getIAAHostIcon (int);
#endif
bool PluginHostType::isInterAppAudioConnected() const
{
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
return juce_isInterAppAudioConnected();
#endif
return false;
}
void PluginHostType::switchToHostApplication() const
{
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
juce_switchToHostApplication();
#endif
}
bool PluginHostType::isInAAXAudioSuite (AudioProcessor& processor)
{
#if JucePlugin_Build_AAX
if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_AAX
&& jucePlugInIsRunningInAudioSuiteFn != nullptr)
{
return jucePlugInIsRunningInAudioSuiteFn (processor);
}
#endif
ignoreUnused (processor);
return false;
}
namespace juce {
extern Image JUCE_API getIconFromApplication (const String&, const int);
Image PluginHostType::getHostIcon (int size) const
{
ignoreUnused (size);
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
if (isInterAppAudioConnected())
return juce_getIAAHostIcon (size);
#endif
#if JUCE_MAC
String bundlePath (getHostPath().upToLastOccurrenceOf (".app", true, true));
return getIconFromApplication (bundlePath, size);
#endif
return Image();
}
}

+ 41
- 51
libs/juce-current/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm View File

@@ -499,17 +499,11 @@ public:
float normaliseParamValue (float scaledValue) const noexcept
{
if (discrete)
return scaledValue / (getNumSteps() - 1);
return (scaledValue - minValue) / range;
}
float scaleParamValue (float normalisedValue) const noexcept
{
if (discrete)
return normalisedValue * (getNumSteps() - 1);
return minValue + (range * normalisedValue);
}
@@ -1223,23 +1217,33 @@ public:
}
//==============================================================================
int getNumPrograms() override
struct ScopedFactoryPresets
{
CFArrayRef presets;
UInt32 sz = sizeof (CFArrayRef);
int num = 0;
ScopedFactoryPresets (AudioUnit& au)
{
UInt32 sz = sizeof (CFArrayRef);
if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets,
kAudioUnitScope_Global, 0, &presets, &sz) == noErr)
AudioUnitGetProperty (au, kAudioUnitProperty_FactoryPresets,
kAudioUnitScope_Global, 0, &presets, &sz);
}
~ScopedFactoryPresets()
{
if (presets != nullptr)
{
num = (int) CFArrayGetCount (presets);
CFRelease (presets);
}
}
return num;
CFArrayRef presets = nullptr;
};
int getNumPrograms() override
{
ScopedFactoryPresets factoryPresets { audioUnit };
if (factoryPresets.presets != nullptr)
return (int) CFArrayGetCount (factoryPresets.presets);
return 0;
}
int getCurrentProgram() override
@@ -1256,33 +1260,26 @@ public:
void setCurrentProgram (int newIndex) override
{
AUPreset current;
current.presetNumber = newIndex;
ScopedFactoryPresets factoryPresets { audioUnit };
CFArrayRef presets;
UInt32 sz = sizeof (CFArrayRef);
if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets,
kAudioUnitScope_Global, 0, &presets, &sz) == noErr)
if (factoryPresets.presets != nullptr
&& newIndex < (int) CFArrayGetCount (factoryPresets.presets))
{
if (auto* p = (const AUPreset*) CFArrayGetValueAtIndex (presets, newIndex))
current.presetName = p->presetName;
AUPreset current;
current.presetNumber = newIndex;
CFRelease (presets);
}
if (auto* p = static_cast<const AUPreset*> (CFArrayGetValueAtIndex (factoryPresets.presets, newIndex)))
current.presetName = p->presetName;
AudioUnitSetProperty (audioUnit, kAudioUnitProperty_PresentPreset,
kAudioUnitScope_Global, 0, &current, sizeof (AUPreset));
AudioUnitSetProperty (audioUnit, kAudioUnitProperty_PresentPreset,
kAudioUnitScope_Global, 0, &current, sizeof (AUPreset));
sendAllParametersChangedEvents();
sendAllParametersChangedEvents();
}
}
const String getProgramName (int index) override
{
String s;
CFArrayRef presets;
UInt32 sz = sizeof (CFArrayRef);
if (index == -1)
{
AUPreset current;
@@ -1294,27 +1291,20 @@ public:
AudioUnitGetProperty (audioUnit, kAudioUnitProperty_PresentPreset,
kAudioUnitScope_Global, 0, &current, &prstsz);
s = String::fromCFString (current.presetName);
return String::fromCFString (current.presetName);
}
else if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets,
kAudioUnitScope_Global, 0, &presets, &sz) == noErr)
ScopedFactoryPresets factoryPresets { audioUnit };
if (factoryPresets.presets != nullptr)
{
for (CFIndex i = 0; i < CFArrayGetCount (presets); ++i)
{
if (auto* p = (const AUPreset*) CFArrayGetValueAtIndex (presets, i))
{
for (CFIndex i = 0; i < CFArrayGetCount (factoryPresets.presets); ++i)
if (auto* p = static_cast<const AUPreset*> (CFArrayGetValueAtIndex (factoryPresets.presets, i)))
if (p->presetNumber == index)
{
s = String::fromCFString (p->presetName);
break;
}
}
}
CFRelease (presets);
return String::fromCFString (p->presetName);
}
return s;
return {};
}
void changeProgramName (int /*index*/, const String& /*newName*/) override
@@ -1471,7 +1461,7 @@ public:
info.defaultValue,
(info.flags & kAudioUnitParameterFlag_NonRealTime) == 0,
isDiscrete,
isDiscrete ? (int) (info.maxValue + 1.0f) : AudioProcessor::getDefaultNumParameterSteps(),
isDiscrete ? (int) (info.maxValue - info.minValue + 1.0f) : AudioProcessor::getDefaultNumParameterSteps(),
isBoolean,
label,
(info.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0);


+ 56
- 50
libs/juce-current/source/modules/juce_audio_processors/format_types/juce_VST3Common.h View File

@@ -266,31 +266,33 @@ static Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (const Audio
{
using namespace Steinberg::Vst::SpeakerArr;
if (channels == AudioChannelSet::disabled()) return kEmpty;
else if (channels == AudioChannelSet::mono()) return kMono;
else if (channels == AudioChannelSet::stereo()) return kStereo;
else if (channels == AudioChannelSet::createLCR()) return k30Cine;
else if (channels == AudioChannelSet::createLRS()) return k30Music;
else if (channels == AudioChannelSet::createLCRS()) return k40Cine;
else if (channels == AudioChannelSet::create5point0()) return k50;
else if (channels == AudioChannelSet::create5point1()) return k51;
else if (channels == AudioChannelSet::create6point0()) return k60Cine;
else if (channels == AudioChannelSet::create6point1()) return k61Cine;
else if (channels == AudioChannelSet::create6point0Music()) return k60Music;
else if (channels == AudioChannelSet::create6point1Music()) return k61Music;
else if (channels == AudioChannelSet::create7point0()) return k70Music;
else if (channels == AudioChannelSet::create7point0SDDS()) return k70Cine;
else if (channels == AudioChannelSet::create7point1()) return k71CineSideFill;
else if (channels == AudioChannelSet::create7point1SDDS()) return k71Cine;
else if (channels == AudioChannelSet::ambisonic()) return kAmbi1stOrderACN;
else if (channels == AudioChannelSet::quadraphonic()) return k40Music;
else if (channels == AudioChannelSet::create7point0point2()) return k71_2 & ~(Steinberg::Vst::kSpeakerLfe);
else if (channels == AudioChannelSet::create7point1point2()) return k71_2;
else if (channels == AudioChannelSet::ambisonic (0)) return (1ull << 20);
else if (channels == AudioChannelSet::ambisonic (1)) return (1ull << 20) | (1ull << 21) | (1ull << 22) | (1ull << 23);
if (channels == AudioChannelSet::disabled()) return kEmpty;
if (channels == AudioChannelSet::mono()) return kMono;
if (channels == AudioChannelSet::stereo()) return kStereo;
if (channels == AudioChannelSet::createLCR()) return k30Cine;
if (channels == AudioChannelSet::createLRS()) return k30Music;
if (channels == AudioChannelSet::createLCRS()) return k40Cine;
if (channels == AudioChannelSet::create5point0()) return k50;
if (channels == AudioChannelSet::create5point1()) return k51;
if (channels == AudioChannelSet::create6point0()) return k60Cine;
if (channels == AudioChannelSet::create6point1()) return k61Cine;
if (channels == AudioChannelSet::create6point0Music()) return k60Music;
if (channels == AudioChannelSet::create6point1Music()) return k61Music;
if (channels == AudioChannelSet::create7point0()) return k70Music;
if (channels == AudioChannelSet::create7point0SDDS()) return k70Cine;
if (channels == AudioChannelSet::create7point1()) return k71CineSideFill;
if (channels == AudioChannelSet::create7point1SDDS()) return k71Cine;
if (channels == AudioChannelSet::ambisonic()) return kAmbi1stOrderACN;
if (channels == AudioChannelSet::quadraphonic()) return k40Music;
if (channels == AudioChannelSet::create7point0point2()) return k71_2 & ~(Steinberg::Vst::kSpeakerLfe);
if (channels == AudioChannelSet::create7point1point2()) return k71_2;
if (channels == AudioChannelSet::create7point0point4()) return k71_4 & ~(Steinberg::Vst::kSpeakerLfe);
if (channels == AudioChannelSet::create7point1point4()) return k71_4;
if (channels == AudioChannelSet::ambisonic (0)) return (1ull << 20);
if (channels == AudioChannelSet::ambisonic (1)) return (1ull << 20) | (1ull << 21) | (1ull << 22) | (1ull << 23);
#if VST_VERSION >= 0x030608
else if (channels == AudioChannelSet::ambisonic (2)) return kAmbi2cdOrderACN;
else if (channels == AudioChannelSet::ambisonic (3)) return kAmbi3rdOrderACN;
if (channels == AudioChannelSet::ambisonic (2)) return kAmbi2cdOrderACN;
if (channels == AudioChannelSet::ambisonic (3)) return kAmbi3rdOrderACN;
#endif
Steinberg::Vst::SpeakerArrangement result = 0;
@@ -307,32 +309,36 @@ static AudioChannelSet getChannelSetForSpeakerArrangement (Steinberg::Vst::Speak
{
using namespace Steinberg::Vst::SpeakerArr;
if (arr == kEmpty) return AudioChannelSet::disabled();
else if (arr == kMono) return AudioChannelSet::mono();
else if (arr == kStereo) return AudioChannelSet::stereo();
else if (arr == k30Cine) return AudioChannelSet::createLCR();
else if (arr == k30Music) return AudioChannelSet::createLRS();
else if (arr == k40Cine) return AudioChannelSet::createLCRS();
else if (arr == k50) return AudioChannelSet::create5point0();
else if (arr == k51) return AudioChannelSet::create5point1();
else if (arr == k60Cine) return AudioChannelSet::create6point0();
else if (arr == k61Cine) return AudioChannelSet::create6point1();
else if (arr == k60Music) return AudioChannelSet::create6point0Music();
else if (arr == k61Music) return AudioChannelSet::create6point1Music();
else if (arr == k70Music) return AudioChannelSet::create7point0();
else if (arr == k70Cine) return AudioChannelSet::create7point0SDDS();
else if (arr == k71CineSideFill) return AudioChannelSet::create7point1();
else if (arr == k71Cine) return AudioChannelSet::create7point1SDDS();
else if (arr == kAmbi1stOrderACN) return AudioChannelSet::ambisonic();
else if (arr == k40Music) return AudioChannelSet::quadraphonic();
else if (arr == k71_2) return AudioChannelSet::create7point1point2();
else if (arr == (k71_2 & ~(Steinberg::Vst::kSpeakerLfe))) return AudioChannelSet::create7point0point2();
else if (arr == (1 << 20)) return AudioChannelSet::ambisonic (0);
else if (arr == ((1 << 20) | (1 << 21) | (1 << 22) | (1 << 23))) return AudioChannelSet::ambisonic (1);
#if VST_VERSION >= 0x030608
else if (arr == kAmbi2cdOrderACN) return AudioChannelSet::ambisonic (2);
else if (arr == kAmbi3rdOrderACN) return AudioChannelSet::ambisonic (3);
#endif
switch (arr)
{
case kEmpty: return AudioChannelSet::disabled();
case kMono: return AudioChannelSet::mono();
case kStereo: return AudioChannelSet::stereo();
case k30Cine: return AudioChannelSet::createLCR();
case k30Music: return AudioChannelSet::createLRS();
case k40Cine: return AudioChannelSet::createLCRS();
case k50: return AudioChannelSet::create5point0();
case k51: return AudioChannelSet::create5point1();
case k60Cine: return AudioChannelSet::create6point0();
case k61Cine: return AudioChannelSet::create6point1();
case k60Music: return AudioChannelSet::create6point0Music();
case k61Music: return AudioChannelSet::create6point1Music();
case k70Music: return AudioChannelSet::create7point0();
case k70Cine: return AudioChannelSet::create7point0SDDS();
case k71CineSideFill: return AudioChannelSet::create7point1();
case k71Cine: return AudioChannelSet::create7point1SDDS();
case k40Music: return AudioChannelSet::quadraphonic();
case k71_2: return AudioChannelSet::create7point1point2();
case k71_2 & ~(Steinberg::Vst::kSpeakerLfe): return AudioChannelSet::create7point0point2();
case k71_4: return AudioChannelSet::create7point1point4();
case k71_4 & ~(Steinberg::Vst::kSpeakerLfe): return AudioChannelSet::create7point0point4();
case (1 << 20): return AudioChannelSet::ambisonic (0);
case kAmbi1stOrderACN: return AudioChannelSet::ambisonic (1);
#if VST_VERSION >= 0x030608
case kAmbi2cdOrderACN: return AudioChannelSet::ambisonic (2);
case kAmbi3rdOrderACN: return AudioChannelSet::ambisonic (3);
#endif
}
AudioChannelSet result;


+ 1
- 0
libs/juce-current/source/modules/juce_audio_processors/juce_audio_processors.cpp View File

@@ -253,3 +253,4 @@ struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewCompone
#include "utilities/juce_AudioParameterChoice.cpp"
#include "utilities/juce_ParameterAttachments.cpp"
#include "utilities/juce_AudioProcessorValueTreeState.cpp"
#include "utilities/juce_PluginHostType.cpp"

+ 1
- 0
libs/juce-current/source/modules/juce_audio_processors/juce_audio_processors.h View File

@@ -142,3 +142,4 @@
#include "utilities/juce_AudioParameterChoice.h"
#include "utilities/juce_ParameterAttachments.h"
#include "utilities/juce_AudioProcessorValueTreeState.h"
#include "utilities/juce_PluginHostType.h"

+ 309
- 0
libs/juce-current/source/modules/juce_audio_processors/utilities/juce_PluginHostType.cpp View File

@@ -0,0 +1,309 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
void JUCE_CALLTYPE juce_switchToHostApplication();
juce::Image JUCE_CALLTYPE juce_getIAAHostIcon (int);
#endif
namespace juce
{
Image JUCE_API getIconFromApplication (const String&, const int);
AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined;
std::function<bool (AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioSuiteFn = nullptr;
String PluginHostType::hostIdReportedByWrapper;
bool PluginHostType::isInterAppAudioConnected() const
{
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
return juce_isInterAppAudioConnected();
#endif
return false;
}
void PluginHostType::switchToHostApplication() const
{
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
juce_switchToHostApplication();
#endif
}
bool PluginHostType::isInAAXAudioSuite (AudioProcessor& processor)
{
#if JucePlugin_Build_AAX
if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_AAX
&& jucePlugInIsRunningInAudioSuiteFn != nullptr)
{
return jucePlugInIsRunningInAudioSuiteFn (processor);
}
#endif
ignoreUnused (processor);
return false;
}
Image PluginHostType::getHostIcon (int size) const
{
ignoreUnused (size);
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
if (isInterAppAudioConnected())
return juce_getIAAHostIcon (size);
#endif
#if JUCE_MAC
String bundlePath (getHostPath().upToLastOccurrenceOf (".app", true, true));
return getIconFromApplication (bundlePath, size);
#endif
return Image();
}
const char* PluginHostType::getHostDescription() const noexcept
{
switch (type)
{
case AbletonLive6: return "Ableton Live 6";
case AbletonLive7: return "Ableton Live 7";
case AbletonLive8: return "Ableton Live 8";
case AbletonLive9: return "Ableton Live 9";
case AbletonLive10: return "Ableton Live 10";
case AbletonLiveGeneric: return "Ableton Live";
case AdobeAudition: return "Adobe Audition";
case AdobePremierePro: return "Adobe Premiere";
case AppleGarageBand: return "Apple GarageBand";
case AppleLogic: return "Apple Logic";
case AppleMainStage: return "Apple MainStage";
case Ardour: return "Ardour";
case AvidProTools: return "ProTools";
case BitwigStudio: return "Bitwig Studio";
case CakewalkSonar8: return "Cakewalk Sonar 8";
case CakewalkSonarGeneric: return "Cakewalk Sonar";
case CakewalkByBandlab: return "Cakewalk by Bandlab";
case DaVinciResolve: return "DaVinci Resolve";
case DigitalPerformer: return "DigitalPerformer";
case FinalCut: return "Final Cut";
case FruityLoops: return "FruityLoops";
case JUCEPluginHost: return "JUCE AudioPluginHost";
case MagixSamplitude: return "Magix Samplitude";
case MagixSequoia: return "Magix Sequoia";
case pluginval: return "pluginval";
case MergingPyramix: return "Pyramix";
case MuseReceptorGeneric: return "Muse Receptor";
case Reaper: return "Reaper";
case Reason: return "Reason";
case Renoise: return "Renoise";
case SADiE: return "SADiE";
case SteinbergCubase4: return "Steinberg Cubase 4";
case SteinbergCubase5: return "Steinberg Cubase 5";
case SteinbergCubase5Bridged: return "Steinberg Cubase 5 Bridged";
case SteinbergCubase6: return "Steinberg Cubase 6";
case SteinbergCubase7: return "Steinberg Cubase 7";
case SteinbergCubase8: return "Steinberg Cubase 8";
case SteinbergCubase8_5: return "Steinberg Cubase 8.5";
case SteinbergCubase9: return "Steinberg Cubase 9";
case SteinbergCubase9_5: return "Steinberg Cubase 9.5";
case SteinbergCubase10: return "Steinberg Cubase 10";
case SteinbergCubase10_5: return "Steinberg Cubase 10.5";
case SteinbergCubaseGeneric: return "Steinberg Cubase";
case SteinbergNuendo3: return "Steinberg Nuendo 3";
case SteinbergNuendo4: return "Steinberg Nuendo 4";
case SteinbergNuendo5: return "Steinberg Nuendo 5";
case SteinbergNuendoGeneric: return "Steinberg Nuendo";
case SteinbergWavelab5: return "Steinberg Wavelab 5";
case SteinbergWavelab6: return "Steinberg Wavelab 6";
case SteinbergWavelab7: return "Steinberg Wavelab 7";
case SteinbergWavelab8: return "Steinberg Wavelab 8";
case SteinbergWavelabGeneric: return "Steinberg Wavelab";
case SteinbergTestHost: return "Steinberg TestHost";
case StudioOne: return "Studio One";
case Tracktion3: return "Tracktion 3";
case TracktionGeneric: return "Tracktion";
case TracktionWaveform: return "Tracktion Waveform";
case VBVSTScanner: return "VBVSTScanner";
case ViennaEnsemblePro: return "Vienna Ensemble Pro";
case WaveBurner: return "WaveBurner";
case UnknownHost:
default: break;
}
return "Unknown";
}
PluginHostType::HostType PluginHostType::getHostType()
{
auto hostPath = getHostPath();
auto hostFilename = File (hostPath).getFileName();
#if JUCE_MAC
if (hostPath.containsIgnoreCase ("Final Cut Pro.app")) return FinalCut;
if (hostPath.containsIgnoreCase ("Final Cut Pro Trial.app")) return FinalCut;
if (hostPath.containsIgnoreCase ("Live 6")) return AbletonLive6;
if (hostPath.containsIgnoreCase ("Live 7")) return AbletonLive7;
if (hostPath.containsIgnoreCase ("Live 8")) return AbletonLive8;
if (hostPath.containsIgnoreCase ("Live 9")) return AbletonLive9;
if (hostPath.containsIgnoreCase ("Live 10")) return AbletonLive10;
if (hostFilename.containsIgnoreCase ("Live")) return AbletonLiveGeneric;
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
if (hostFilename.containsIgnoreCase ("Pro Tools")) return AvidProTools;
if (hostFilename.containsIgnoreCase ("Nuendo 3")) return SteinbergNuendo3;
if (hostFilename.containsIgnoreCase ("Nuendo 4")) return SteinbergNuendo4;
if (hostFilename.containsIgnoreCase ("Nuendo 5")) return SteinbergNuendo5;
if (hostFilename.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
if (hostFilename.containsIgnoreCase ("Cubase 4")) return SteinbergCubase4;
if (hostFilename.containsIgnoreCase ("Cubase 5")) return SteinbergCubase5;
if (hostFilename.containsIgnoreCase ("Cubase 6")) return SteinbergCubase6;
if (hostFilename.containsIgnoreCase ("Cubase 7")) return SteinbergCubase7;
if (hostPath.containsIgnoreCase ("Cubase 8.app")) return SteinbergCubase8;
if (hostPath.containsIgnoreCase ("Cubase 8.5.app")) return SteinbergCubase8_5;
if (hostPath.containsIgnoreCase ("Cubase 9.app")) return SteinbergCubase9;
if (hostPath.containsIgnoreCase ("Cubase 9.5.app")) return SteinbergCubase9_5;
if (hostPath.containsIgnoreCase ("Cubase 10.app")) return SteinbergCubase10;
if (hostPath.containsIgnoreCase ("Cubase 10.5.app")) return SteinbergCubase10_5;
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
if (hostFilename.containsIgnoreCase ("WaveBurner")) return WaveBurner;
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
if (hostFilename.containsIgnoreCase ("OsxFL")) return FruityLoops;
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
if (hostIdReportedByWrapper == "com.apple.logic.pro") return AppleLogic;
if (hostIdReportedByWrapper == "com.apple.garageband") return AppleGarageBand;
if (hostIdReportedByWrapper == "com.apple.mainstage") return AppleMainStage;
const auto procName = nsStringToJuce ([[NSRunningApplication currentApplication] localizedName]);
const auto matchesInOrder = [&] (const StringArray& strings)
{
return procName.matchesWildcard ("AUHostingService*(" + strings.joinIntoString ("*") + ")", false);
};
// Depending on localization settings, spaces are not always plain ascii spaces
if (matchesInOrder ({ "Logic", "Pro" })) return AppleLogic;
if (matchesInOrder ({ "GarageBand" })) return AppleGarageBand;
if (matchesInOrder ({ "MainStage" })) return AppleMainStage;
if (matchesInOrder ({ "Final", "Cut", "Pro" })) return FinalCut;
#elif JUCE_WINDOWS
if (hostFilename.containsIgnoreCase ("Live 6")) return AbletonLive6;
if (hostFilename.containsIgnoreCase ("Live 7")) return AbletonLive7;
if (hostFilename.containsIgnoreCase ("Live 8")) return AbletonLive8;
if (hostFilename.containsIgnoreCase ("Live 9")) return AbletonLive9;
if (hostFilename.containsIgnoreCase ("Live 10")) return AbletonLive10;
if (hostFilename.containsIgnoreCase ("Live ")) return AbletonLiveGeneric;
if (hostFilename.containsIgnoreCase ("Audition")) return AdobeAudition;
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
if (hostFilename.containsIgnoreCase ("ProTools")) return AvidProTools;
if (hostPath.containsIgnoreCase ("SONAR 8")) return CakewalkSonar8;
if (hostFilename.containsIgnoreCase ("SONAR")) return CakewalkSonarGeneric;
if (hostFilename.containsIgnoreCase ("Cakewalk.exe")) return CakewalkByBandlab;
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
if (hostFilename.containsIgnoreCase ("Cubase4")) return SteinbergCubase4;
if (hostFilename.containsIgnoreCase ("Cubase5")) return SteinbergCubase5;
if (hostFilename.containsIgnoreCase ("Cubase6")) return SteinbergCubase6;
if (hostFilename.containsIgnoreCase ("Cubase7")) return SteinbergCubase7;
if (hostFilename.containsIgnoreCase ("Cubase8.exe")) return SteinbergCubase8;
if (hostFilename.containsIgnoreCase ("Cubase8.5.exe")) return SteinbergCubase8_5;
// Later version of Cubase scan plug-ins with a separate executable "vst2xscanner"
if (hostFilename.containsIgnoreCase ("Cubase9.5.exe")
|| hostPath.containsIgnoreCase ("Cubase 9.5")) return SteinbergCubase9_5;
if (hostFilename.containsIgnoreCase ("Cubase9.exe")
|| hostPath.containsIgnoreCase ("Cubase 9")) return SteinbergCubase9;
if (hostFilename.containsIgnoreCase ("Cubase10.5.exe")
|| hostPath.containsIgnoreCase ("Cubase 10.5")) return SteinbergCubase10_5;
if (hostFilename.containsIgnoreCase ("Cubase10.exe")
|| hostPath.containsIgnoreCase ("Cubase 10")) return SteinbergCubase10;
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
if (hostFilename.containsIgnoreCase ("VSTBridgeApp")) return SteinbergCubase5Bridged;
if (hostPath.containsIgnoreCase ("Wavelab 5")) return SteinbergWavelab5;
if (hostPath.containsIgnoreCase ("Wavelab 6")) return SteinbergWavelab6;
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
if (hostPath.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
if (hostFilename.containsIgnoreCase ("TestHost")) return SteinbergTestHost;
if (hostFilename.containsIgnoreCase ("rm-host")) return MuseReceptorGeneric;
if (hostFilename.startsWith ("FL")) return FruityLoops;
if (hostFilename.contains ("ilbridge.")) return FruityLoops;
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
if (hostFilename.containsIgnoreCase ("VST_Scanner")) return VBVSTScanner;
if (hostPath.containsIgnoreCase ("Merging Technologies")) return MergingPyramix;
if (hostFilename.startsWithIgnoreCase ("Sam")) return MagixSamplitude;
if (hostFilename.startsWithIgnoreCase ("Sequoia")) return MagixSequoia;
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
if (hostPath.containsIgnoreCase ("Bitwig Studio")) return BitwigStudio;
if (hostFilename.containsIgnoreCase ("Sadie")) return SADiE;
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
#elif JUCE_LINUX
if (hostFilename.containsIgnoreCase ("Ardour")) return Ardour;
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
#elif JUCE_IOS
#elif JUCE_ANDROID
#else
#error
#endif
return UnknownHost;
}
} // namespace juce

+ 242
- 0
libs/juce-current/source/modules/juce_audio_processors/utilities/juce_PluginHostType.h View File

@@ -0,0 +1,242 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
A useful utility class to determine the host or DAW in which your plugin is
loaded.
Declare a PluginHostType object in your class to use it.
@tags{Audio}
*/
class PluginHostType
{
public:
//==============================================================================
PluginHostType() : type (getHostType()) {}
PluginHostType (const PluginHostType& other) = default;
PluginHostType& operator= (const PluginHostType& other) = default;
//==============================================================================
/** Represents the host type and also its version for some hosts. */
enum HostType
{
UnknownHost, /**< Represents an unknown host. */
AbletonLive6, /**< Represents Ableton Live 6. */
AbletonLive7, /**< Represents Ableton Live 7. */
AbletonLive8, /**< Represents Ableton Live 8. */
AbletonLive9, /**< Represents Ableton Live 9. */
AbletonLive10, /**< Represents Ableton Live 10. */
AbletonLiveGeneric, /**< Represents Ableton Live. */
AdobeAudition, /**< Represents Adobe Audition. */
AdobePremierePro, /**< Represents Adobe Premiere Pro. */
AppleGarageBand, /**< Represents Apple GarageBand. */
AppleLogic, /**< Represents Apple Logic Pro. */
AppleMainStage, /**< Represents Apple Main Stage. */
Ardour, /**< Represents Ardour. */
AvidProTools, /**< Represents Avid Pro Tools. */
BitwigStudio, /**< Represents Bitwig Studio. */
CakewalkSonar8, /**< Represents Cakewalk Sonar 8. */
CakewalkSonarGeneric, /**< Represents Cakewalk Sonar. */
CakewalkByBandlab, /**< Represents Cakewalk by Bandlab. */
DaVinciResolve, /**< Represents DaVinci Resolve. */
DigitalPerformer, /**< Represents Digital Performer. */
FinalCut, /**< Represents Apple Final Cut Pro. */
FruityLoops, /**< Represents Fruity Loops. */
JUCEPluginHost, /**< Represents the JUCE AudioPluginHost */
MagixSamplitude, /**< Represents Magix Samplitude. */
MagixSequoia, /**< Represents Magix Sequoia. */
MergingPyramix, /**< Represents Merging Pyramix. */
MuseReceptorGeneric, /**< Represents Muse Receptor. */
pluginval, /**< Represents pluginval. */
Reaper, /**< Represents Cockos Reaper. */
Reason, /**< Represents Reason. */
Renoise, /**< Represents Renoise. */
SADiE, /**< Represents SADiE. */
SteinbergCubase4, /**< Represents Steinberg Cubase 4. */
SteinbergCubase5, /**< Represents Steinberg Cubase 5. */
SteinbergCubase5Bridged, /**< Represents Steinberg Cubase 5 Bridged. */
SteinbergCubase6, /**< Represents Steinberg Cubase 6. */
SteinbergCubase7, /**< Represents Steinberg Cubase 7. */
SteinbergCubase8, /**< Represents Steinberg Cubase 8. */
SteinbergCubase8_5, /**< Represents Steinberg Cubase 8.5. */
SteinbergCubase9, /**< Represents Steinberg Cubase 9. */
SteinbergCubase9_5, /**< Represents Steinberg Cubase 9.5. */
SteinbergCubase10, /**< Represents Steinberg Cubase 10. */
SteinbergCubase10_5, /**< Represents Steinberg Cubase 10.5. */
SteinbergCubaseGeneric, /**< Represents Steinberg Cubase. */
SteinbergNuendo3, /**< Represents Steinberg Nuendo 3. */
SteinbergNuendo4, /**< Represents Steinberg Nuendo 4. */
SteinbergNuendo5, /**< Represents Steinberg Nuendo 5. */
SteinbergNuendoGeneric, /**< Represents Steinberg Nuendo. */
SteinbergWavelab5, /**< Represents Steinberg Wavelab 5. */
SteinbergWavelab6, /**< Represents Steinberg Wavelab 6. */
SteinbergWavelab7, /**< Represents Steinberg Wavelab 7. */
SteinbergWavelab8, /**< Represents Steinberg Wavelab 8. */
SteinbergWavelabGeneric, /**< Represents Steinberg Wavelab. */
SteinbergTestHost, /**< Represents Steinberg's VST3 Test Host. */
StudioOne, /**< Represents PreSonus Studio One. */
Tracktion3, /**< Represents Tracktion 3. */
TracktionGeneric, /**< Represents Tracktion. */
TracktionWaveform, /**< Represents Tracktion Waveform. */
VBVSTScanner, /**< Represents VB Audio VST Scanner. */
ViennaEnsemblePro, /**< Represents Vienna Ensemble Pro. */
WaveBurner /**< Represents Apple WaveBurner. */
};
HostType type;
//==============================================================================
/** Returns true if the host is any version of Ableton Live. */
bool isAbletonLive() const noexcept { return type == AbletonLive6 || type == AbletonLive7 || type == AbletonLive8
|| type == AbletonLive9 || type == AbletonLive10 || type == AbletonLiveGeneric; }
/** Returns true if the host is Adobe Audition. */
bool isAdobeAudition() const noexcept { return type == AdobeAudition; }
/** Returns true if the host is Ardour. */
bool isArdour() const noexcept { return type == Ardour; }
/** Returns true if the host is Bitwig Studio. */
bool isBitwigStudio() const noexcept { return type == BitwigStudio; }
/** Returns true if the host is any version of Steinberg Cubase. */
bool isCubase() const noexcept { return type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase5Bridged || type == SteinbergCubase6
|| type == SteinbergCubase7 || type == SteinbergCubase8 || type == SteinbergCubase8_5 || type == SteinbergCubase9
|| type == SteinbergCubase9_5 || type == SteinbergCubase10 || type == SteinbergCubase10_5 || type == SteinbergCubaseGeneric; }
/** Returns true if the host is Steinberg Cubase 7 or later. */
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); }
/** Returns true if the host is Steinberg Cubase 5 Bridged. */
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; }
/** Returns true if the host is DaVinci Resolve. */
bool isDaVinciResolve() const noexcept { return type == DaVinciResolve; }
/** Returns true if the host is Digital Performer. */
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
/** Returns true if the host is Apple Final Cut Pro. */
bool isFinalCut() const noexcept { return type == FinalCut; }
/** Returns true if the host is Fruity Loops. */
bool isFruityLoops() const noexcept { return type == FruityLoops; }
/** Returns true if the host is Apple GarageBand. */
bool isGarageBand() const noexcept { return type == AppleGarageBand; }
/** Returns true if the host is the JUCE AudioPluginHost */
bool isJUCEPluginHost() const noexcept { return type == JUCEPluginHost; }
/** Returns true if the host is Apple Logic Pro. */
bool isLogic() const noexcept { return type == AppleLogic; }
/** Returns true if the host is Apple MainStage. */
bool isMainStage() const noexcept { return type == AppleMainStage; }
/** Returns true if the host is any version of Steinberg Nuendo. */
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; }
/** Returns true if the host is pluginval. */
bool isPluginval() const noexcept { return type == pluginval; }
/** Returns true if the host is Adobe Premiere Pro. */
bool isPremiere() const noexcept { return type == AdobePremierePro; }
/** Returns true if the host is Avid Pro Tools. */
bool isProTools() const noexcept { return type == AvidProTools; }
/** Returns true if the host is Merging Pyramix. */
bool isPyramix() const noexcept { return type == MergingPyramix; }
/** Returns true if the host is Muse Receptor. */
bool isReceptor() const noexcept { return type == MuseReceptorGeneric; }
/** Returns true if the host is Cockos Reaper. */
bool isReaper() const noexcept { return type == Reaper; }
/** Returns true if the host is Reason. */
bool isReason() const noexcept { return type == Reason; }
/** Returns true if the host is Renoise. */
bool isRenoise() const noexcept { return type == Renoise; }
/** Returns true if the host is SADiE. */
bool isSADiE() const noexcept { return type == SADiE; }
/** Returns true if the host is Magix Samplitude. */
bool isSamplitude() const noexcept { return type == MagixSamplitude; }
/** Returns true if the host is Magix Sequoia. */
bool isSequoia() const noexcept { return type == MagixSequoia; }
/** Returns true if the host is any version of Cakewalk Sonar. */
bool isSonar() const noexcept { return type == CakewalkSonar8 || type == CakewalkSonarGeneric || type == CakewalkByBandlab; }
/** Returns true if the host is Steinberg's VST3 Test Host. */
bool isSteinbergTestHost() const noexcept { return type == SteinbergTestHost; }
/** Returns true if the host is any product from Steinberg. */
bool isSteinberg() const noexcept { return isCubase() || isNuendo() || isWavelab() || isSteinbergTestHost(); }
/** Returns true if the host is PreSonus Studio One. */
bool isStudioOne() const noexcept { return type == StudioOne; }
/** Returns true if the host is any version of Tracktion. */
bool isTracktion() const noexcept { return type == Tracktion3 || type == TracktionGeneric || isTracktionWaveform(); }
/** Returns true if the host is Tracktion Waveform. */
bool isTracktionWaveform() const noexcept { return type == TracktionWaveform; }
/** Returns true if the host is VB Audio VST Scanner. */
bool isVBVSTScanner() const noexcept { return type == VBVSTScanner; }
/** Returns true if the host is Vienna Ensemble Pro. */
bool isViennaEnsemblePro() const noexcept { return type == ViennaEnsemblePro; }
/** Returns true if the host is Apple WaveBurner. */
bool isWaveBurner() const noexcept { return type == WaveBurner; }
/** Returns true if the host is any version of Steinberg WaveLab. */
bool isWavelab() const noexcept { return isWavelabLegacy() || type == SteinbergWavelab7 || type == SteinbergWavelab8 || type == SteinbergWavelabGeneric; }
/** Returns true if the host is Steinberg WaveLab 6 or below. */
bool isWavelabLegacy() const noexcept { return type == SteinbergWavelab5 || type == SteinbergWavelab6; }
//==============================================================================
/** Returns a human-readable description of the host. */
const char* getHostDescription() const noexcept;
//==============================================================================
/** Returns true if the plugin is connected with Inter-App Audio on iOS. */
bool isInterAppAudioConnected() const;
/** Switches to the host application when Inter-App Audio is used on iOS. */
void switchToHostApplication() const;
/** Gets the host app's icon when Inter-App Audio is used on iOS. */
Image getHostIcon (int size) const;
//==============================================================================
/** Returns the complete absolute path of the host application executable. */
static String getHostPath()
{
return File::getSpecialLocation (File::hostApplicationPath).getFullPathName();
}
//==============================================================================
/**
Returns the plug-in format via which the plug-in file was loaded. This value is
identical to AudioProcessor::wrapperType of the main audio processor of this
plug-in. This function is useful for code that does not have access to the
plug-in's main audio processor.
@see AudioProcessor::wrapperType
*/
static AudioProcessor::WrapperType getPluginLoadedAs() noexcept { return jucePlugInClientCurrentWrapperType; }
/** Returns true if the AudioProcessor instance is an AAX plug-in running in AudioSuite. */
static bool isInAAXAudioSuite (AudioProcessor&);
//==============================================================================
#ifndef DOXYGEN
// @internal
static AudioProcessor::WrapperType jucePlugInClientCurrentWrapperType;
static std::function<bool (AudioProcessor&)> jucePlugInIsRunningInAudioSuiteFn;
static String hostIdReportedByWrapper;
#endif
private:
static HostType getHostType();
};
} // namespace juce

+ 2
- 0
libs/juce-current/source/modules/juce_dsp/frequency/juce_Convolution.cpp View File

@@ -781,6 +781,8 @@ private:
if (wantsNormalise == Convolution::Normalise::yes)
normaliseImpulseResponse (resampled);
else
resampled.applyGain ((float) (originalSampleRate / processSpec.sampleRate));
const auto currentLatency = jmax (processSpec.maximumBlockSize, (uint32) latency.latencyInSamples);
const auto maxBufferSize = shouldBeZeroLatency ? static_cast<int> (processSpec.maximumBlockSize)


+ 5
- 2
libs/juce-current/source/modules/juce_dsp/frequency/juce_Convolution_test.cpp View File

@@ -514,6 +514,9 @@ public:
AudioBuffer<float> result (original.getNumChannels(), finalSize);
resamplingSource.getNextAudioBlock ({ &result, 0, result.getNumSamples() });
result.applyGain ((float) resampleRatio);
return result;
}();
@@ -550,10 +553,10 @@ public:
const auto ramp = makeRamp (static_cast<int> (spec.maximumBlockSize) * 8);
using BlockSize = decltype (spec.maximumBlockSize);
for (auto latency : { /*static_cast<BlockSize> (0),
for (auto latency : { static_cast<BlockSize> (0),
spec.maximumBlockSize / 3,
spec.maximumBlockSize,
spec.maximumBlockSize * 2, */
spec.maximumBlockSize * 2,
static_cast<BlockSize> (spec.maximumBlockSize * 2.5) })
{
testConvolution (spec,


+ 1
- 0
libs/juce-current/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp View File

@@ -1288,6 +1288,7 @@ PopupMenu::Options LookAndFeel_V2::getOptionsForComboBoxPopupMenu (ComboBox& box
{
return PopupMenu::Options().withTargetComponent (&box)
.withItemThatMustBeVisible (box.getSelectedId())
.withInitiallySelectedItem (box.getSelectedId())
.withMinimumWidth (box.getWidth())
.withMaximumNumColumns (1)
.withStandardItemHeight (label.getHeight());


+ 38
- 32
libs/juce-current/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp View File

@@ -252,12 +252,19 @@ struct MenuWindow : public Component
setOpaque (lf.findColour (PopupMenu::backgroundColourId).isOpaque()
|| ! Desktop::canUseSemiTransparentWindows());
const auto initialSelectedId = options.getInitiallySelectedItemId();
for (int i = 0; i < menu.items.size(); ++i)
{
auto& item = menu.items.getReference (i);
if (i + 1 < menu.items.size() || ! item.isSeparator)
items.add (new ItemComponent (item, options, *this));
{
auto* child = items.add (new ItemComponent (item, options, *this));
if (initialSelectedId != 0 && item.itemID == initialSelectedId)
setCurrentlyHighlightedChild (child);
}
}
auto targetArea = options.getTargetScreenArea() / scaleFactor;
@@ -1239,7 +1246,7 @@ private:
{
if (globalMousePos != lastMousePos || timeNow > lastMouseMoveTime + 350)
{
const bool isMouseOver = window.reallyContains (localMousePos, true);
const auto isMouseOver = window.reallyContains (localMousePos, true);
if (isMouseOver)
window.hasBeenOver = true;
@@ -1279,7 +1286,12 @@ private:
window.activeSubMenu->hide (nullptr, true);
if (! isMouseOver)
{
if (! window.hasBeenOver)
return;
itemUnderMouse = nullptr;
}
window.setCurrentlyHighlightedChild (itemUnderMouse);
}
@@ -1751,10 +1763,16 @@ PopupMenu::Options::Options()
targetArea.setPosition (Desktop::getMousePosition());
}
template <typename Member, typename Item>
static PopupMenu::Options with (PopupMenu::Options options, Member&& member, Item&& item)
{
options.*member = std::forward<Item> (item);
return options;
}
PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* comp) const
{
Options o (*this);
o.targetComponent = comp;
auto o = with (*this, &Options::targetComponent, comp);
if (comp != nullptr)
o.targetArea = comp->getScreenBounds();
@@ -1769,66 +1787,54 @@ PopupMenu::Options PopupMenu::Options::withTargetComponent (Component& comp) con
PopupMenu::Options PopupMenu::Options::withTargetScreenArea (Rectangle<int> area) const
{
Options o (*this);
o.targetArea = area;
return o;
return with (*this, &Options::targetArea, area);
}
PopupMenu::Options PopupMenu::Options::withDeletionCheck (Component& comp) const
{
Options o (*this);
o.componentToWatchForDeletion = &comp;
o.isWatchingForDeletion = true;
return o;
return with (with (*this, &Options::isWatchingForDeletion, true),
&Options::componentToWatchForDeletion,
&comp);
}
PopupMenu::Options PopupMenu::Options::withMinimumWidth (int w) const
{
Options o (*this);
o.minWidth = w;
return o;
return with (*this, &Options::minWidth, w);
}
PopupMenu::Options PopupMenu::Options::withMinimumNumColumns (int cols) const
{
Options o (*this);
o.minColumns = cols;
return o;
return with (*this, &Options::minColumns, cols);
}
PopupMenu::Options PopupMenu::Options::withMaximumNumColumns (int cols) const
{
Options o (*this);
o.maxColumns = cols;
return o;
return with (*this, &Options::maxColumns, cols);
}
PopupMenu::Options PopupMenu::Options::withStandardItemHeight (int height) const
{
Options o (*this);
o.standardHeight = height;
return o;
return with (*this, &Options::standardHeight, height);
}
PopupMenu::Options PopupMenu::Options::withItemThatMustBeVisible (int idOfItemToBeVisible) const
{
Options o (*this);
o.visibleItemID = idOfItemToBeVisible;
return o;
return with (*this, &Options::visibleItemID, idOfItemToBeVisible);
}
PopupMenu::Options PopupMenu::Options::withParentComponent (Component* parent) const
{
Options o (*this);
o.parentComponent = parent;
return o;
return with (*this, &Options::parentComponent, parent);
}
PopupMenu::Options PopupMenu::Options::withPreferredPopupDirection (PopupDirection direction) const
{
Options o (*this);
o.preferredPopupDirection = direction;
return o;
return with (*this, &Options::preferredPopupDirection, direction);
}
PopupMenu::Options PopupMenu::Options::withInitiallySelectedItem (int idOfItemToBeSelected) const
{
return with (*this, &Options::initiallySelectedItemId, idOfItemToBeSelected);
}
Component* PopupMenu::createWindow (const Options& options,


+ 3
- 1
libs/juce-current/source/modules/juce_gui_basics/menus/juce_PopupMenu.h View File

@@ -470,6 +470,7 @@ public:
Options withItemThatMustBeVisible (int idOfItemToBeVisible) const;
Options withParentComponent (Component* parentComponent) const;
Options withPreferredPopupDirection (PopupDirection direction) const;
Options withInitiallySelectedItem (int idOfItemToBeSelected) const;
//==============================================================================
Component* getParentComponent() const noexcept { return parentComponent; }
@@ -482,6 +483,7 @@ public:
int getStandardItemHeight() const noexcept { return standardHeight; }
int getItemThatMustBeVisible() const noexcept { return visibleItemID; }
PopupDirection getPreferredPopupDirection() const noexcept { return preferredPopupDirection; }
int getInitiallySelectedItemId() const noexcept { return initiallySelectedItemId; }
private:
//==============================================================================
@@ -489,7 +491,7 @@ public:
Component* targetComponent = nullptr;
Component* parentComponent = nullptr;
WeakReference<Component> componentToWatchForDeletion;
int visibleItemID = 0, minWidth = 0, minColumns = 1, maxColumns = 0, standardHeight = 0;
int visibleItemID = 0, minWidth = 0, minColumns = 1, maxColumns = 0, standardHeight = 0, initiallySelectedItemId = 0;
bool isWatchingForDeletion = false;
PopupDirection preferredPopupDirection = PopupDirection::downwards;
};


+ 14
- 4
libs/juce-current/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -41,6 +41,9 @@ public:
// it's dangerous to create a window on a thread other than the message thread.
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
if (! XWindowSystem::getInstance()->isX11Available())
return;
if (isAlwaysOnTop)
++numAlwaysOnTopPeers;
@@ -80,8 +83,13 @@ public:
//==============================================================================
void setBounds (const Rectangle<int>& newBounds, bool isNowFullScreen) override
{
bounds = newBounds.withSize (jmax (1, newBounds.getWidth()),
jmax (1, newBounds.getHeight()));
const auto correctedNewBounds = newBounds.withSize (jmax (1, newBounds.getWidth()),
jmax (1, newBounds.getHeight()));
if (bounds == correctedNewBounds && fullScreen == isNowFullScreen)
return;
bounds = correctedNewBounds;
updateScaleFactorFromNewBounds (bounds, false);
@@ -262,12 +270,14 @@ public:
//==============================================================================
void repaint (const Rectangle<int>& area) override
{
repainter->repaint (area.getIntersection (bounds.withZeroOrigin()));
if (repainter != nullptr)
repainter->repaint (area.getIntersection (bounds.withZeroOrigin()));
}
void performAnyPendingRepaintsNow() override
{
repainter->performAnyPendingRepaintsNow();
if (repainter != nullptr)
repainter->performAnyPendingRepaintsNow();
}
void setIcon (const Image& newIcon) override


+ 34
- 16
libs/juce-current/source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp View File

@@ -69,7 +69,7 @@ public:
}
}
~Win32NativeFileChooser()
~Win32NativeFileChooser() override
{
signalThreadShouldExit();
waitForThreadToExit (-1);
@@ -105,7 +105,7 @@ public:
shouldCancel = true;
if (auto hwnd = nativeDialogRef.get())
EndDialog (hwnd, 0);
PostMessage (hwnd, WM_CLOSE, 0, 0);
}
Component* getCustomComponent() { return customComponent.get(); }
@@ -237,25 +237,24 @@ private:
ScopedLock lock (owner.deletingDialog);