Large diffs are not rendered by default.

File renamed without changes.
99 changes: 99 additions & 0 deletions libs/juce6.1/patches/05_mingw-fixes.patch
@@ -0,0 +1,99 @@
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 54a7cb635..d475d93e2 100644
--- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
+++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
@@ -61,7 +61,7 @@ JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996 4100)
#define PRAGMA_ALIGN_SUPPORTED 1
#endif

-#if ! JUCE_MSVC
+#if ! JUCE_WINDOWS
#define __cdecl
#endif

diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
index 91e82f087..211246aed 100644
--- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
+++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
@@ -64,9 +64,6 @@ JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4355)
#ifndef WM_APPCOMMAND
#define WM_APPCOMMAND 0x0319
#endif
-
- extern "C" void _fpreset();
- extern "C" void _clearfp();
#elif ! JUCE_WINDOWS
static void _fpreset() {}
static void _clearfp() {}
diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp
index 644774631..fed316924 100644
--- a/modules/juce_gui_basics/juce_gui_basics.cpp
+++ b/modules/juce_gui_basics/juce_gui_basics.cpp
@@ -67,9 +67,12 @@
#include <vfw.h>
#include <commdlg.h>
#include <commctrl.h>
- #include <UIAutomation.h>
#include <sapi.h>

+ #if JUCE_MSVC
+ #include <UIAutomation.h>
+ #endif
+
#if JUCE_WEB_BROWSER
#include <exdisp.h>
#include <exdispid.h>
@@ -308,13 +311,15 @@ JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#include "native/juce_mac_MouseCursor.mm"

#elif JUCE_WINDOWS
- #include "native/accessibility/juce_win32_ComInterfaces.h"
- #include "native/accessibility/juce_win32_WindowsUIAWrapper.h"
- #include "native/accessibility/juce_win32_AccessibilityElement.h"
- #include "native/accessibility/juce_win32_UIAHelpers.h"
- #include "native/accessibility/juce_win32_UIAProviders.h"
- #include "native/accessibility/juce_win32_AccessibilityElement.cpp"
- #include "native/accessibility/juce_win32_Accessibility.cpp"
+ #if JUCE_MSVC
+ #include "native/accessibility/juce_win32_ComInterfaces.h"
+ #include "native/accessibility/juce_win32_WindowsUIAWrapper.h"
+ #include "native/accessibility/juce_win32_AccessibilityElement.h"
+ #include "native/accessibility/juce_win32_UIAHelpers.h"
+ #include "native/accessibility/juce_win32_UIAProviders.h"
+ #include "native/accessibility/juce_win32_AccessibilityElement.cpp"
+ #include "native/accessibility/juce_win32_Accessibility.cpp"
+ #endif
#include "native/juce_win32_Windowing.cpp"
#include "native/juce_win32_DragAndDrop.cpp"
#include "native/juce_win32_FileChooser.cpp"
diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
index 4ffc09d9a..e5886ca31 100644
--- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
+++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
@@ -1519,8 +1519,10 @@ public:
// do this first to avoid messages arriving for this window before it's destroyed
JuceWindowIdentifier::setAsJUCEWindow (hwnd, false);

+ #if JUCE_MSVC
if (isAccessibilityActive)
WindowsAccessibility::revokeUIAMapEntriesForWindow (hwnd);
+ #endif

shadower = nullptr;
currentTouches.deleteAllTouchesForPeer (this);
@@ -4052,6 +4054,7 @@ private:
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS;

+ #if JUCE_MSVC
case WM_GETOBJECT:
{
if (static_cast<long> (lParam) == WindowsAccessibility::getUiaRootObjectId())
@@ -4070,6 +4073,7 @@ private:

break;
}
+ #endif
default:
break;
}
@@ -1,10 +1,10 @@
diff --git a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp
index 19f1d7ac7..8ffe16b06 100644
index f06e0781d..4914d918c 100644
--- a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp
+++ b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp
@@ -25,7 +25,7 @@

#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX
#if JUCE_PLUGINHOST_LADSPA && (JUCE_LINUX || JUCE_BSD)

-#include <ladspa.h>
+#include "ladspa.h"
Expand Down
@@ -1,5 +1,5 @@
diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp
index b980441c9..670cb3969 100644
index 038fbb5d7..d450e9a5a 100644
--- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp
+++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp
@@ -40,8 +40,6 @@ AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : proce
Expand Down Expand Up @@ -32,47 +32,47 @@ index b980441c9..670cb3969 100644
-
- // END SECTION A
-
resizable = false;

attachConstrainer (&defaultConstrainer);
resizeListener.reset (new AudioProcessorEditorListener (*this));
addComponentListener (resizeListener.get());
diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h
index ff694b78f..07d3765f4 100644
index 896d018c7..88e342e97 100644
--- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h
+++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h
@@ -206,7 +206,6 @@ private:
bool resizable;
@@ -235,7 +235,6 @@ private:
ComponentBoundsConstrainer defaultConstrainer;
ComponentBoundsConstrainer* constrainer = {};
ComponentBoundsConstrainer* constrainer = nullptr;
AudioProcessorEditorHostContext* hostContext = nullptr;
- Component::SafePointer<Component> splashScreen;
AffineTransform hostScaleTransform;

JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor)
diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp
index 056ff591b..a4d798606 100644
index fed316924..2e0036430 100644
--- a/modules/juce_gui_basics/juce_gui_basics.cpp
+++ b/modules/juce_gui_basics/juce_gui_basics.cpp
@@ -218,7 +218,6 @@ namespace juce
#include "application/juce_Application.cpp"
@@ -250,7 +250,6 @@ namespace juce
#include "misc/juce_BubbleComponent.cpp"
#include "misc/juce_DropShadower.cpp"
#include "misc/juce_FocusOutline.cpp"
-#include "misc/juce_JUCESplashScreen.cpp"

#include "layout/juce_FlexBox.cpp"
#include "layout/juce_GridItem.cpp"
diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h
index 729461282..a4873d04b 100644
index 5eaf306fc..205dc36f6 100644
--- a/modules/juce_gui_basics/juce_gui_basics.h
+++ b/modules/juce_gui_basics/juce_gui_basics.h
@@ -250,7 +250,6 @@ namespace juce
#include "menus/juce_BurgerMenuComponent.h"
@@ -262,7 +262,6 @@ namespace juce
#include "buttons/juce_ToolbarButton.h"
#include "misc/juce_DropShadower.h"
#include "misc/juce_FocusOutline.h"
-#include "misc/juce_JUCESplashScreen.h"
#include "widgets/juce_TreeView.h"
#include "windows/juce_TopLevelWindow.h"
#include "windows/juce_AlertWindow.h"
#include "windows/juce_MessageBoxOptions.h"
diff --git a/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp b/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp
index dc3c7279a..d1d20d6c7 100644
index 437475c7e..74f8e709d 100644
--- a/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp
+++ b/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp
@@ -41,8 +41,6 @@ ResizableWindow::ResizableWindow (const String& name, Colour bkgnd, bool shouldA
Expand Down Expand Up @@ -113,10 +113,10 @@ index dc3c7279a..d1d20d6c7 100644

lastNonFullScreenPos.setBounds (50, 50, 256, 256);
diff --git a/modules/juce_gui_basics/windows/juce_ResizableWindow.h b/modules/juce_gui_basics/windows/juce_ResizableWindow.h
index d67303595..e59f620c1 100644
index e185adde4..521331dff 100644
--- a/modules/juce_gui_basics/windows/juce_ResizableWindow.h
+++ b/modules/juce_gui_basics/windows/juce_ResizableWindow.h
@@ -383,7 +383,7 @@ protected:
@@ -391,7 +391,7 @@ protected:

private:
//==============================================================================
Expand Down
@@ -1,8 +1,8 @@
diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h
index 082a5697a..c79ca18ea 100644
index dbf06043a..8bdfd4629 100644
--- a/modules/juce_core/native/juce_posix_SharedCode.h
+++ b/modules/juce_core/native/juce_posix_SharedCode.h
@@ -600,12 +600,39 @@ File juce_getExecutableFile()
@@ -611,12 +611,39 @@ File juce_getExecutableFile()

auto localSymbol = (void*) juce_getExecutableFile;
dladdr (localSymbol, &exeInfo);
Expand Down
@@ -1,16 +1,15 @@
diff --git a/modules/juce_core/native/juce_linux_Files.cpp b/modules/juce_core/native/juce_linux_Files.cpp
index d2a302e3e..3dc4602ce 100644
index 22f989acf..e5dc06676 100644
--- a/modules/juce_core/native/juce_linux_Files.cpp
+++ b/modules/juce_core/native/juce_linux_Files.cpp
@@ -211,15 +211,21 @@ bool Process::openDocument (const String& fileName, const String& parameters)
@@ -223,15 +223,21 @@ bool Process::openDocument (const String& fileName, const String& parameters)

const char* const argv[4] = { "/bin/sh", "-c", cmdString.toUTF8(), nullptr };
const char* const argv[] = { "/bin/sh", "-c", cmdString.toUTF8(), nullptr };

- auto cpid = fork();
+#if JUCE_USE_VFORK
+ const auto cpid = vfork();
+#else
+ const auto cpid = fork();
const auto cpid = fork();
+#endif

if (cpid == 0)
Expand All @@ -22,25 +21,26 @@ index d2a302e3e..3dc4602ce 100644
// Child process
- execve (argv[0], (char**) argv, environ);
- exit (0);
+ if (execvp (argv[0], (char**) argv) < 0)
+ if (execve (argv[0], (char**) argv, environ) < 0)
+ _exit (0);
}

return cpid >= 0;
diff --git a/modules/juce_core/native/juce_mac_Files.mm b/modules/juce_core/native/juce_mac_Files.mm
index 1a4d07516..f385a089f 100644
index eff20c841..f67e7871a 100644
--- a/modules/juce_core/native/juce_mac_Files.mm
+++ b/modules/juce_core/native/juce_mac_Files.mm
@@ -92,23 +92,22 @@ namespace MacFileHelpers
#else
static bool launchExecutable (const String& pathAndArguments)
{
- auto cpid = fork();
+ const char* const argv[4] = { "/bin/sh", "-c", pathAndArguments.toUTF8(), nullptr };
+
+#if JUCE_USE_VFORK
+ const auto cpid = vfork();
+#else
auto cpid = fork();
+ const auto cpid = fork();
+#endif

if (cpid == 0)
Expand All @@ -65,10 +65,10 @@ index 1a4d07516..f385a089f 100644
#endif
}
diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h
index c79ca18ea..ad46cf390 100644
index 8bdfd4629..2e96f3b04 100644
--- a/modules/juce_core/native/juce_posix_SharedCode.h
+++ b/modules/juce_core/native/juce_posix_SharedCode.h
@@ -1104,7 +1104,18 @@ public:
@@ -1125,7 +1125,18 @@ public:

if (pipe (pipeHandles) == 0)
{
Expand All @@ -88,15 +88,15 @@ index c79ca18ea..ad46cf390 100644

if (result < 0)
{
@@ -1113,6 +1124,7 @@ public:
@@ -1134,6 +1145,7 @@ public:
}
else if (result == 0)
{
+#if ! JUCE_USE_VFORK
// we're the child process..
close (pipeHandles[0]); // close the read handle

@@ -1127,17 +1139,10 @@ public:
@@ -1148,17 +1160,10 @@ public:
dup2 (open ("/dev/null", O_WRONLY), STDERR_FILENO);

close (pipeHandles[1]);
Expand Down
@@ -1,8 +1,8 @@
diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h
index ad46cf390..13724ba7c 100644
index 2e96f3b04..f4bb0b84f 100644
--- a/modules/juce_core/native/juce_posix_SharedCode.h
+++ b/modules/juce_core/native/juce_posix_SharedCode.h
@@ -1239,6 +1239,11 @@ public:
@@ -1260,6 +1260,11 @@ public:
return 0;
}

Expand All @@ -15,10 +15,10 @@ index ad46cf390..13724ba7c 100644
int pipeHandle = 0;
int exitCode = -1;
diff --git a/modules/juce_core/native/juce_win32_Threads.cpp b/modules/juce_core/native/juce_win32_Threads.cpp
index 4a4148119..1c38ff2cf 100644
index 1a4004353..5f64b9e72 100644
--- a/modules/juce_core/native/juce_win32_Threads.cpp
+++ b/modules/juce_core/native/juce_win32_Threads.cpp
@@ -477,6 +477,11 @@ public:
@@ -487,6 +487,11 @@ public:
return (uint32) exitCode;
}

Expand All @@ -31,7 +31,7 @@ index 4a4148119..1c38ff2cf 100644

private:
diff --git a/modules/juce_core/threads/juce_ChildProcess.cpp b/modules/juce_core/threads/juce_ChildProcess.cpp
index 3b284c25a..31e9c8d94 100644
index 2e5f14330..ab36fbace 100644
--- a/modules/juce_core/threads/juce_ChildProcess.cpp
+++ b/modules/juce_core/threads/juce_ChildProcess.cpp
@@ -81,6 +81,11 @@ String ChildProcess::readAllProcessOutput()
Expand Down
@@ -1,5 +1,5 @@
diff --git a/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp b/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp
index b799ee2e4..803740c63 100644
index 283502159..a9fcce2b7 100644
--- a/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp
+++ b/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp
@@ -26,6 +26,7 @@
Expand All @@ -10,7 +10,7 @@ index b799ee2e4..803740c63 100644
static bool exeIsAvailable (String executable)
{
ChildProcess child;
@@ -245,10 +246,11 @@ private:
@@ -255,10 +256,11 @@ private:

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Native)
};
Expand All @@ -23,13 +23,15 @@ index b799ee2e4..803740c63 100644
return false;
#else
static bool canUseNativeBox = exeIsAvailable ("zenity") || exeIsAvailable ("kdialog");
@@ -258,7 +260,11 @@ bool FileChooser::isPlatformDialogAvailable()
@@ -268,7 +270,13 @@ bool FileChooser::isPlatformDialogAvailable()

FileChooser::Pimpl* FileChooser::showPlatformDialog (FileChooser& owner, int flags, FilePreviewComponent*)
std::shared_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, FilePreviewComponent*)
{
+#if JUCE_MODAL_LOOPS_PERMITTED
return new Native (owner, flags);
return std::make_shared<Native> (owner, flags);
+#else
+ ignoreUnused (owner);
+ ignoreUnused (flags);
+ return nullptr;
+#endif
}
Expand Down
@@ -1,8 +1,21 @@
diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp
index 0c7da61de..ca9ff3b90 100644
--- a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp
+++ b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp
@@ -842,7 +842,7 @@ void MainHostWindow::showAudioSettings()
o.componentToCentreAround = this;
o.dialogBackgroundColour = getLookAndFeel().findColour (ResizableWindow::backgroundColourId);
o.escapeKeyTriggersCloseButton = true;
- o.useNativeTitleBar = false;
+ o.useNativeTitleBar = true;
o.resizable = false;

auto* w = o.create();
diff --git a/modules/juce_gui_basics/windows/juce_DialogWindow.cpp b/modules/juce_gui_basics/windows/juce_DialogWindow.cpp
index ea2675d59..92bf09e16 100644
index 37067b2fe..f0ffad5d4 100644
--- a/modules/juce_gui_basics/windows/juce_DialogWindow.cpp
+++ b/modules/juce_gui_basics/windows/juce_DialogWindow.cpp
@@ -131,7 +131,8 @@ void DialogWindow::showDialog (const String& dialogTitle,
@@ -134,7 +134,8 @@ void DialogWindow::showDialog (const String& dialogTitle,
Colour backgroundColour,
const bool escapeKeyTriggersCloseButton,
const bool resizable,
Expand All @@ -12,7 +25,7 @@ index ea2675d59..92bf09e16 100644
{
LaunchOptions o;
o.dialogTitle = dialogTitle;
@@ -139,9 +140,9 @@ void DialogWindow::showDialog (const String& dialogTitle,
@@ -142,9 +143,9 @@ void DialogWindow::showDialog (const String& dialogTitle,
o.componentToCentreAround = componentToCentreAround;
o.dialogBackgroundColour = backgroundColour;
o.escapeKeyTriggersCloseButton = escapeKeyTriggersCloseButton;
Expand All @@ -23,7 +36,7 @@ index ea2675d59..92bf09e16 100644

o.launchAsync();
}
@@ -153,7 +154,8 @@ int DialogWindow::showModalDialog (const String& dialogTitle,
@@ -156,7 +157,8 @@ int DialogWindow::showModalDialog (const String& dialogTitle,
Colour backgroundColour,
const bool escapeKeyTriggersCloseButton,
const bool resizable,
Expand All @@ -33,7 +46,7 @@ index ea2675d59..92bf09e16 100644
{
LaunchOptions o;
o.dialogTitle = dialogTitle;
@@ -161,9 +163,9 @@ int DialogWindow::showModalDialog (const String& dialogTitle,
@@ -164,9 +166,9 @@ int DialogWindow::showModalDialog (const String& dialogTitle,
o.componentToCentreAround = componentToCentreAround;
o.dialogBackgroundColour = backgroundColour;
o.escapeKeyTriggersCloseButton = escapeKeyTriggersCloseButton;
Expand All @@ -45,26 +58,52 @@ index ea2675d59..92bf09e16 100644
return o.runModal();
}
diff --git a/modules/juce_gui_basics/windows/juce_DialogWindow.h b/modules/juce_gui_basics/windows/juce_DialogWindow.h
index a10211525..de9ef2f4b 100644
index faf25900f..a7ed9734b 100644
--- a/modules/juce_gui_basics/windows/juce_DialogWindow.h
+++ b/modules/juce_gui_basics/windows/juce_DialogWindow.h
@@ -193,7 +193,8 @@ public:
@@ -199,7 +199,8 @@ public:
Colour backgroundColour,
bool escapeKeyTriggersCloseButton,
bool shouldBeResizable = false,
- bool useBottomRightCornerResizer = false);
+ bool useBottomRightCornerResizer = false,
+ bool useNativeTitleBar = false);
+ bool useNativeTitleBar = true);

#if JUCE_MODAL_LOOPS_PERMITTED || DOXYGEN
#if JUCE_MODAL_LOOPS_PERMITTED
/** Easy way of quickly showing a dialog box containing a given component.
@@ -239,7 +240,8 @@ public:
@@ -245,7 +246,8 @@ public:
Colour backgroundColour,
bool escapeKeyTriggersCloseButton,
bool shouldBeResizable = false,
- bool useBottomRightCornerResizer = false);
+ bool useBottomRightCornerResizer = false,
+ bool useNativeTitleBar = false);
+ bool useNativeTitleBar = true);
#endif


diff --git a/modules/juce_gui_basics/windows/juce_TopLevelWindow.h b/modules/juce_gui_basics/windows/juce_TopLevelWindow.h
index 92ec8eca4..7bdca6698 100644
--- a/modules/juce_gui_basics/windows/juce_TopLevelWindow.h
+++ b/modules/juce_gui_basics/windows/juce_TopLevelWindow.h
@@ -154,7 +154,7 @@ protected:
private:
friend class TopLevelWindowManager;
friend class ResizableWindow;
- bool useDropShadow = true, useNativeTitleBar = false, isCurrentlyActive = false;
+ bool useDropShadow = true, useNativeTitleBar = true, isCurrentlyActive = false;
std::unique_ptr<DropShadower> shadower;

std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
diff --git a/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp b/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp
index f3efdc347..82407343c 100644
--- a/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp
+++ b/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp
@@ -92,7 +92,7 @@ void PreferencesPanel::showInDialogBox (const String& dialogTitle, int dialogWid
o.dialogTitle = dialogTitle;
o.dialogBackgroundColour = backgroundColour;
o.escapeKeyTriggersCloseButton = false;
- o.useNativeTitleBar = false;
+ o.useNativeTitleBar = true;
o.resizable = false;

o.launchAsync();
@@ -1,8 +1,8 @@
diff --git a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
index 6ad01c68a..490a3a792 100644
index 2ea809908..ee9615b02 100644
--- a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
+++ b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
@@ -2804,10 +2804,14 @@ void XWindowSystem::setWindowType (::Window windowH, int styleFlags) const
@@ -2939,10 +2939,14 @@ void XWindowSystem::setWindowType (::Window windowH, int styleFlags) const

if (atoms.windowType != None)
{
Expand Down
14 changes: 14 additions & 0 deletions libs/juce6.1/patches/15_fix-usage-with-vestige.patch
@@ -0,0 +1,14 @@
diff --git a/modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h b/modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h
index 1a56fcf22..5a433ac82 100644
--- a/modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h
+++ b/modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h
@@ -63,7 +63,9 @@ typedef AudioComponentInstance AudioUnit;
}
@endcode
*/
+#ifndef _VESTIGE_H
struct AEffect;
+#endif

//==============================================================================
namespace juce
@@ -1,8 +1,8 @@
diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h
index ae60fde15..dbad562ef 100644
index d4ef6fb4a..1062b14f9 100644
--- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h
+++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h
@@ -1116,6 +1116,11 @@ public:
@@ -1118,6 +1118,11 @@ public:
/** This method is called when the layout of the audio processor changes. */
virtual void processorLayoutsChanged();

Expand All @@ -14,7 +14,7 @@ index ae60fde15..dbad562ef 100644
//==============================================================================
/** Adds a listener that will be called when an aspect of this processor changes. */
virtual void addListener (AudioProcessorListener* newListener);
@@ -1200,6 +1205,7 @@ public:
@@ -1202,6 +1207,7 @@ public:
wrapperType_AudioUnitv3,
wrapperType_RTAS,
wrapperType_AAX,
Expand Down
@@ -1,8 +1,8 @@
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 94f6bf569..ddbe6fd65 100644
index d475d93e2..7c3cdf702 100644
--- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
+++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
@@ -294,9 +294,6 @@ public:
@@ -252,9 +252,6 @@ public:
// You must at least have some channels
jassert (processor->isMidiEffect() || (maxNumInChannels > 0 || maxNumOutChannels > 0));

Expand Down
@@ -1,8 +1,8 @@
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 7e2122580..cff9b7a88 100644
index 7c3cdf702..98cdd68a1 100644
--- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
+++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
@@ -1841,7 +1841,7 @@ private:
@@ -1799,7 +1799,7 @@ private:

pointer_sized_int handleGetPlugInName (VstOpCodeArguments args)
{
Expand Down
304 changes: 304 additions & 0 deletions libs/juce6.1/patches/21_audioprocessor-no-gui.patch
@@ -0,0 +1,304 @@
diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp
index 49c6e390e..6640a8aff 100644
--- a/modules/juce_audio_processors/juce_audio_processors.cpp
+++ b/modules/juce_audio_processors/juce_audio_processors.cpp
@@ -34,7 +34,9 @@

#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#define JUCE_CORE_INCLUDE_OBJC_HELPERS 1
-#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
+ #define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
+#endif
#define JUCE_GUI_BASICS_INCLUDE_SCOPED_THREAD_DPI_AWARENESS_SETTER 1
#define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1

@@ -49,7 +51,7 @@
#endif
#endif

-#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && (JUCE_LINUX || JUCE_BSD)
+#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && (JUCE_LINUX || JUCE_BSD) && ! JUCE_AUDIOPROCESSOR_NO_GUI
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <sys/utsname.h>
@@ -188,17 +190,21 @@ private:
#include "format_types/juce_LegacyAudioParameter.cpp"
#include "processors/juce_AudioProcessor.cpp"
#include "processors/juce_AudioPluginInstance.cpp"
-#include "processors/juce_AudioProcessorEditor.cpp"
#include "processors/juce_AudioProcessorGraph.cpp"
-#include "processors/juce_GenericAudioProcessorEditor.cpp"
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
+ #include "processors/juce_AudioProcessorEditor.cpp"
+ #include "processors/juce_GenericAudioProcessorEditor.cpp"
+#endif
#include "processors/juce_PluginDescription.cpp"
#include "format_types/juce_LADSPAPluginFormat.cpp"
#include "format_types/juce_VSTPluginFormat.cpp"
#include "format_types/juce_VST3PluginFormat.cpp"
#include "format_types/juce_AudioUnitPluginFormat.mm"
-#include "scanning/juce_KnownPluginList.cpp"
-#include "scanning/juce_PluginDirectoryScanner.cpp"
-#include "scanning/juce_PluginListComponent.cpp"
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
+ #include "scanning/juce_KnownPluginList.cpp"
+ #include "scanning/juce_PluginDirectoryScanner.cpp"
+ #include "scanning/juce_PluginListComponent.cpp"
+#endif
#include "processors/juce_AudioProcessorParameterGroup.cpp"
#include "utilities/juce_AudioProcessorParameterWithID.cpp"
#include "utilities/juce_RangedAudioParameter.cpp"
@@ -206,6 +212,13 @@ private:
#include "utilities/juce_AudioParameterInt.cpp"
#include "utilities/juce_AudioParameterBool.cpp"
#include "utilities/juce_AudioParameterChoice.cpp"
-#include "utilities/juce_ParameterAttachments.cpp"
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
+ #include "utilities/juce_ParameterAttachments.cpp"
+#endif
#include "utilities/juce_AudioProcessorValueTreeState.cpp"
#include "utilities/juce_PluginHostType.cpp"
+
+#if JUCE_AUDIOPROCESSOR_NO_GUI
+// commonly used classes in DSP code
+namespace juce { Colour::Colour(juce::uint32) noexcept {} }
+#endif
diff --git a/modules/juce_audio_processors/juce_audio_processors.h b/modules/juce_audio_processors/juce_audio_processors.h
index 6e6b90e97..25dcf0f06 100644
--- a/modules/juce_audio_processors/juce_audio_processors.h
+++ b/modules/juce_audio_processors/juce_audio_processors.h
@@ -122,14 +122,18 @@
#include "processors/juce_AudioProcessorParameter.h"
#include "processors/juce_HostedAudioProcessorParameter.h"
#include "processors/juce_AudioProcessorEditorHostContext.h"
-#include "processors/juce_AudioProcessorEditor.h"
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
+ #include "processors/juce_AudioProcessorEditor.h"
+#endif
#include "processors/juce_AudioProcessorListener.h"
#include "processors/juce_AudioProcessorParameterGroup.h"
#include "processors/juce_AudioProcessor.h"
#include "processors/juce_PluginDescription.h"
#include "processors/juce_AudioPluginInstance.h"
#include "processors/juce_AudioProcessorGraph.h"
-#include "processors/juce_GenericAudioProcessorEditor.h"
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
+ #include "processors/juce_GenericAudioProcessorEditor.h"
+#endif
#include "format/juce_AudioPluginFormat.h"
#include "format/juce_AudioPluginFormatManager.h"
#include "scanning/juce_KnownPluginList.h"
@@ -146,6 +150,8 @@
#include "utilities/juce_AudioParameterInt.h"
#include "utilities/juce_AudioParameterBool.h"
#include "utilities/juce_AudioParameterChoice.h"
-#include "utilities/juce_ParameterAttachments.h"
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
+ #include "utilities/juce_ParameterAttachments.h"
+#endif
#include "utilities/juce_AudioProcessorValueTreeState.h"
#include "utilities/juce_PluginHostType.h"
diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
index fbf91cb84..8c84aec59 100644
--- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
+++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
@@ -50,12 +50,14 @@ AudioProcessor::AudioProcessor (const BusesProperties& ioConfig)

AudioProcessor::~AudioProcessor()
{
+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
{
const ScopedLock sl (activeEditorLock);

// ooh, nasty - the editor should have been deleted before its AudioProcessor.
jassert (activeEditor == nullptr);
}
+ #endif

#if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING
// This will fail if you've called beginParameterChangeGesture() for one
@@ -865,6 +867,7 @@ void AudioProcessor::audioIOChanged (bool busNumberChanged, bool channelNumChang
processorLayoutsChanged();
}

+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
//==============================================================================
void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept
{
@@ -901,6 +904,7 @@ AudioProcessorEditor* AudioProcessor::createEditorIfNeeded()

return ed;
}
+#endif

//==============================================================================
void AudioProcessor::getCurrentProgramStateInformation (juce::MemoryBlock& destData)
diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h
index 1062b14f9..120e5571e 100644
--- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h
+++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h
@@ -928,6 +928,7 @@ public:
*/
virtual void setNonRealtime (bool isNonRealtime) noexcept;

+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
//==============================================================================
/** Creates the processor's GUI.

@@ -977,6 +978,7 @@ public:
This may call createEditor() internally to create the component.
*/
AudioProcessorEditor* createEditorIfNeeded();
+ #endif

//==============================================================================
/** Returns the default number of steps for a parameter.
@@ -1193,9 +1195,11 @@ public:

virtual CurveData getResponseCurve (CurveData::Type /*curveType*/) const { return {}; }

+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
//==============================================================================
/** Not for public use - this is called before deleting an editor component. */
void editorBeingDeleted (AudioProcessorEditor*) noexcept;
+ #endif

/** Flags to indicate the type of plugin context in which a processor is being used. */
enum WrapperType
@@ -1226,7 +1230,9 @@ public:
struct TrackProperties
{
String name; // The name of the track - this will be empty if the track name is not known
+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
Colour colour; // The colour of the track - this will be transparentBlack if the colour is not known
+ #endif

// other properties may be added in the future
};
@@ -1469,7 +1475,9 @@ private:

//==============================================================================
Array<AudioProcessorListener*> listeners;
+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
Component::SafePointer<AudioProcessorEditor> activeEditor;
+ #endif
double currentSampleRate = 0;
int blockSize = 0, latencySamples = 0;
bool suspended = false;
diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
index f9999c802..2e114a4ad 100644
--- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
+++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
@@ -1557,8 +1557,10 @@ bool AudioProcessorGraph::AudioGraphIOProcessor::producesMidi() const
bool AudioProcessorGraph::AudioGraphIOProcessor::isInput() const noexcept { return type == audioInputNode || type == midiInputNode; }
bool AudioProcessorGraph::AudioGraphIOProcessor::isOutput() const noexcept { return type == audioOutputNode || type == midiOutputNode; }

+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
bool AudioProcessorGraph::AudioGraphIOProcessor::hasEditor() const { return false; }
AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor() { return nullptr; }
+#endif

int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() { return 0; }
int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; }
diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
index 7b6ab003a..795154b7e 100644
--- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
+++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
@@ -357,8 +357,10 @@ public:
bool acceptsMidi() const override;
bool producesMidi() const override;

+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
bool hasEditor() const override;
AudioProcessorEditor* createEditor() override;
+ #endif

int getNumPrograms() override;
int getCurrentProgram() override;
@@ -394,8 +396,10 @@ public:
bool acceptsMidi() const override;
bool producesMidi() const override;

+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
bool hasEditor() const override { return false; }
AudioProcessorEditor* createEditor() override { return nullptr; }
+ #endif
int getNumPrograms() override { return 0; }
int getCurrentProgram() override { return 0; }
void setCurrentProgram (int) override { }
diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
index bf4b55026..a131040a7 100644
--- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
+++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
@@ -484,6 +484,7 @@ void AudioProcessorValueTreeState::timerCallback()
}

//==============================================================================
+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
template <typename Attachment, typename Control>
std::unique_ptr<Attachment> makeAttachment (const AudioProcessorValueTreeState& stateToUse,
const String& parameterID,
@@ -516,6 +517,7 @@ AudioProcessorValueTreeState::ButtonAttachment::ButtonAttachment (AudioProcessor
: attachment (makeAttachment<ButtonParameterAttachment> (stateToUse, parameterID, button))
{
}
+#endif

//==============================================================================
//==============================================================================
diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
index e1125680f..fdd1b6c98 100644
--- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
+++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
@@ -431,6 +431,7 @@ public:
friend class AudioProcessorValueTreeState::ParameterAdapter;
};

+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
//==============================================================================
/** An object of this class maintains a connection between a Slider and a parameter
in an AudioProcessorValueTreeState.
@@ -498,6 +499,7 @@ public:
std::unique_ptr<ButtonParameterAttachment> attachment;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAttachment)
};
+ #endif

private:
//==============================================================================
diff --git a/modules/juce_audio_processors/utilities/juce_PluginHostType.cpp b/modules/juce_audio_processors/utilities/juce_PluginHostType.cpp
index 6f38cb8ca..6d40cbdd8 100644
--- a/modules/juce_audio_processors/utilities/juce_PluginHostType.cpp
+++ b/modules/juce_audio_processors/utilities/juce_PluginHostType.cpp
@@ -70,6 +70,7 @@ bool PluginHostType::isInAAXAudioSuite (AudioProcessor& processor)
return false;
}

+#if ! JUCE_AUDIOPROCESSOR_NO_GUI
Image PluginHostType::getHostIcon (int size) const
{
ignoreUnused (size);
@@ -86,6 +87,7 @@ Image PluginHostType::getHostIcon (int size) const

return Image();
}
+#endif

const char* PluginHostType::getHostDescription() const noexcept
{
diff --git a/modules/juce_audio_processors/utilities/juce_PluginHostType.h b/modules/juce_audio_processors/utilities/juce_PluginHostType.h
index a11bc52d5..2e2acb3b2 100644
--- a/modules/juce_audio_processors/utilities/juce_PluginHostType.h
+++ b/modules/juce_audio_processors/utilities/juce_PluginHostType.h
@@ -207,8 +207,10 @@ public:
bool isInterAppAudioConnected() const;
/** Switches to the host application when Inter-App Audio is used on iOS. */
void switchToHostApplication() const;
+ #if ! JUCE_AUDIOPROCESSOR_NO_GUI
/** Gets the host app's icon when Inter-App Audio is used on iOS. */
Image getHostIcon (int size) const;
+ #endif

//==============================================================================
/** Returns the complete absolute path of the host application executable. */
@@ -1,24 +1,24 @@
diff --git a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
index 0c1138a2b..a5b42b8ef 100644
--- a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
+++ b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
@@ -172,6 +172,7 @@ private:
diff --git a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
index d00412b35..6cf86fa4c 100644
--- a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
+++ b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
@@ -166,6 +166,7 @@ private:
void operator() (LPWSTR ptr) const noexcept { CoTaskMemFree (ptr); }
};

+ #if JUCE_MSVC
bool showDialog (IFileDialog& dialog, bool async)
{
FILEOPENDIALOGOPTIONS flags = {};
@@ -327,6 +328,7 @@ private:
@@ -383,6 +384,7 @@ private:

return result;
}
+ #endif

Array<URL> openDialogPreVista (bool async)
{
@@ -436,11 +438,13 @@ private:
@@ -499,11 +501,13 @@ private:

const Remover remover (*this);

Expand Down
20 changes: 20 additions & 0 deletions libs/juce6.1/patches/24_vital-extra-opengl-calls.patch
@@ -0,0 +1,20 @@
diff --git a/modules/juce_opengl/native/juce_OpenGLExtensions.h b/modules/juce_opengl/native/juce_OpenGLExtensions.h
index 4f75ae5b7..bacc4b266 100644
--- a/modules/juce_opengl/native/juce_OpenGLExtensions.h
+++ b/modules/juce_opengl/native/juce_OpenGLExtensions.h
@@ -83,7 +83,14 @@ namespace juce
X (glCheckFramebufferStatus) \
X (glFramebufferTexture2D) \
X (glFramebufferRenderbuffer) \
- X (glGetFramebufferAttachmentParameteriv)
+ X (glGetFramebufferAttachmentParameteriv) \
+ X (glTransformFeedbackVaryings) \
+ X (glBeginTransformFeedback) \
+ X (glEndTransformFeedback) \
+ X (glBindBufferBase) \
+ X (glMapBufferRange) \
+ X (glUnmapBuffer)
+

/** @internal This macro contains a list of GL extension functions that need to be dynamically loaded on Windows/Linux.
@see OpenGLExtensionFunctions
91 changes: 91 additions & 0 deletions libs/juce6.1/source/README.md
@@ -0,0 +1,91 @@
![alt text](https://assets.juce.com/juce/JUCE_banner_github.png "JUCE")

JUCE is an open-source cross-platform C++ application framework for creating high quality
desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.
JUCE can be easily integrated with existing projects via CMake, or can be used as a project
generation tool via the [Projucer](https://juce.com/discover/projucer), which supports
exporting projects for Xcode (macOS and iOS), Visual Studio, Android Studio, Code::Blocks
and Linux Makefiles as well as containing a source code editor.

## Getting Started

The JUCE repository contains a [master](https://github.com/juce-framework/JUCE/tree/master)
and [develop](https://github.com/juce-framework/JUCE/tree/develop) branch. The develop branch
contains the latest bugfixes and features and is periodically merged into the master
branch in stable [tagged releases](https://github.com/juce-framework/JUCE/releases)
(the latest release containing pre-built binaries can be also downloaded from the
[JUCE website](https://juce.com/get-juce)).

JUCE projects can be managed with either the Projucer (JUCE's own project-configuration
tool) or with CMake.

### The Projucer

The repository doesn't contain a pre-built Projucer so you will need to build it
for your platform - Xcode, Visual Studio and Linux Makefile projects are located in
[extras/Projucer/Builds](/extras/Projucer/Builds)
(the minimum system requirements are listed in the __System Requirements__ section below).
The Projucer can then be used to create new JUCE projects, view tutorials and run examples.
It is also possible to include the JUCE modules source code in an existing project directly,
or build them into a static or dynamic library which can be linked into a project.

For further help getting started, please refer to the JUCE
[documentation](https://juce.com/learn/documentation) and
[tutorials](https://juce.com/learn/tutorials).

### CMake

Version 3.15 or higher is required. To use CMake, you will need to install it,
either from your system package manager or from the [official download
page](https://cmake.org/download/). For comprehensive documentation on JUCE's
CMake API, see the [JUCE CMake documentation](/docs/CMake%20API.md). For
examples which may be useful as starting points for new CMake projects, see the
[CMake examples directory](/examples/CMake).

#### Building Examples

To use CMake to build the examples and extras bundled with JUCE, simply clone
JUCE and then run the following commands, replacing "DemoRunner" with the name
of the target you wish to build.

cd /path/to/JUCE
cmake . -B cmake-build -DJUCE_BUILD_EXAMPLES=ON -DJUCE_BUILD_EXTRAS=ON
cmake --build cmake-build --target DemoRunner

## Minimum System Requirements

#### Building JUCE Projects

- __macOS/iOS__: Xcode 9.2 (macOS 10.12.6)
- __Windows__: Windows 8.1 and Visual Studio 2015 Update 3 64-bit
- __Linux__: g++ 5.0 or Clang 3.4 (for a full list of dependencies, see
[here](/docs/Linux%20Dependencies.md)).
- __Android__: Android Studio on Windows, macOS or Linux

#### Deployment Targets

- __macOS__: macOS 10.7
- __Windows__: Windows Vista
- __Linux__: Mainstream Linux distributions
- __iOS__: iOS 9.0
- __Android__: Jelly Bean (API 16)

## Contributing

Please see our [contribution guidelines](.github/contributing.md).

## License

The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_core and juce_events)
are permissively licensed under the terms of the
[ISC license](http://www.isc.org/downloads/software-support-policy/isc-license/).
Other modules are covered by a
[GPL/Commercial license](https://www.gnu.org/licenses/gpl-3.0.en.html).

There are multiple commercial licensing tiers for JUCE, with different terms for each:
- JUCE Personal (developers or startup businesses with revenue under 50K USD) - free
- JUCE Indie (small businesses with revenue under 500K USD) - $40/month
- JUCE Pro (no revenue limit) - $130/month
- JUCE Educational (no revenue limit) - free for bona fide educational institutes

For full terms see [LICENSE.md](LICENSE.md).
@@ -0,0 +1,276 @@
/*
==============================================================================
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.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
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 subclass of AudioPlayHead can supply information about the position and
status of a moving play head during audio playback.
One of these can be supplied to an AudioProcessor object so that it can find
out about the position of the audio that it is rendering.
@see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead
@tags{Audio}
*/
class JUCE_API AudioPlayHead
{
protected:
//==============================================================================
AudioPlayHead() = default;

public:
virtual ~AudioPlayHead() = default;

//==============================================================================
/** Frame rate types. */
enum FrameRateType
{
fps23976 = 0,
fps24 = 1,
fps25 = 2,
fps2997 = 3,
fps30 = 4,
fps2997drop = 5,
fps30drop = 6,
fps60 = 7,
fps60drop = 8,
fpsUnknown = 99
};

/** More descriptive frame rate type. */
class JUCE_API FrameRate
{
public:
/** Creates a frame rate with a base rate of 0. */
FrameRate() = default;

/** Creates a FrameRate instance from a FrameRateType. */
FrameRate (FrameRateType type) : FrameRate (fromType (type)) {}

/** Gets the FrameRateType that matches the state of this FrameRate.
Returns fpsUnknown if this FrameRate cannot be represented by any of the
other enum fields.
*/
FrameRateType getType() const
{
switch (base)
{
case 24: return pulldown ? fps23976 : fps24;
case 25: return fps25;
case 30: return pulldown ? (drop ? fps2997drop : fps2997)
: (drop ? fps30drop : fps30);
case 60: return drop ? fps60drop : fps60;
}

return fpsUnknown;
}

/** Returns the plain rate, without taking pulldown into account. */
int getBaseRate() const { return base; }

/** Returns true if drop-frame timecode is in use. */
bool isDrop() const { return drop; }

/** Returns true if the effective framerate is actually equal to the base rate divided by 1.001 */
bool isPullDown() const { return pulldown; }

/** Returns the actual rate described by this object, taking pulldown into account. */
double getEffectiveRate() const { return pulldown ? (double) base / 1.001 : (double) base; }

/** Returns a copy of this object with the specified base rate. */
JUCE_NODISCARD FrameRate withBaseRate (int x) const { return with (&FrameRate::base, x); }

/** Returns a copy of this object with drop frames enabled or disabled, as specified. */
JUCE_NODISCARD FrameRate withDrop (bool x = true) const { return with (&FrameRate::drop, x); }

/** Returns a copy of this object with pulldown enabled or disabled, as specified. */
JUCE_NODISCARD FrameRate withPullDown (bool x = true) const { return with (&FrameRate::pulldown, x); }

/** Returns true if this instance is equal to other. */
bool operator== (const FrameRate& other) const
{
const auto tie = [] (const FrameRate& x) { return std::tie (x.base, x.drop, x.pulldown); };
return tie (*this) == tie (other);
}

/** Returns true if this instance is not equal to other. */
bool operator!= (const FrameRate& other) const { return ! (*this == other); }

private:
static FrameRate fromType (FrameRateType type)
{
switch (type)
{
case fps23976: return FrameRate().withBaseRate (24).withPullDown();
case fps24: return FrameRate().withBaseRate (24);
case fps25: return FrameRate().withBaseRate (25);
case fps2997: return FrameRate().withBaseRate (30).withPullDown();
case fps30: return FrameRate().withBaseRate (30);
case fps2997drop: return FrameRate().withBaseRate (30).withDrop().withPullDown();
case fps30drop: return FrameRate().withBaseRate (30).withDrop();
case fps60: return FrameRate().withBaseRate (60);
case fps60drop: return FrameRate().withBaseRate (60).withDrop();
case fpsUnknown: break;
}

return {};
}

template <typename Member, typename Value>
FrameRate with (Member&& member, Value&& value) const
{
auto copy = *this;
copy.*member = std::forward<Value> (value);
return copy;
}

int base = 0;
bool drop = false, pulldown = false;
};

//==============================================================================
/** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method.
*/
struct JUCE_API CurrentPositionInfo
{
/** The tempo in BPM */
double bpm = 120.0;

/** Time signature numerator, e.g. the 3 of a 3/4 time sig */
int timeSigNumerator = 4;
/** Time signature denominator, e.g. the 4 of a 3/4 time sig */
int timeSigDenominator = 4;

/** The current play position, in samples from the start of the timeline. */
int64 timeInSamples = 0;
/** The current play position, in seconds from the start of the timeline. */
double timeInSeconds = 0;

/** For timecode, the position of the start of the timeline, in seconds from 00:00:00:00. */
double editOriginTime = 0;

/** The current play position, in units of quarter-notes. */
double ppqPosition = 0;

/** The position of the start of the last bar, in units of quarter-notes.
This is the time from the start of the timeline to the start of the current
bar, in ppq units.
Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If
it's not available, the value will be 0.
*/
double ppqPositionOfLastBarStart = 0;

/** The video frame rate, if applicable. */
FrameRate frameRate = FrameRateType::fps23976;

/** True if the transport is currently playing. */
bool isPlaying = false;

/** True if the transport is currently recording.
(When isRecording is true, then isPlaying will also be true).
*/
bool isRecording = false;

/** The current cycle start position in units of quarter-notes.
Note that not all hosts or plugin formats may provide this value.
@see isLooping
*/
double ppqLoopStart = 0;

/** The current cycle end position in units of quarter-notes.
Note that not all hosts or plugin formats may provide this value.
@see isLooping
*/
double ppqLoopEnd = 0;

/** True if the transport is currently looping. */
bool isLooping = false;

//==============================================================================
bool operator== (const CurrentPositionInfo& other) const noexcept
{
const auto tie = [] (const CurrentPositionInfo& i)
{
return std::tie (i.timeInSamples,
i.ppqPosition,
i.editOriginTime,
i.ppqPositionOfLastBarStart,
i.frameRate,
i.isPlaying,
i.isRecording,
i.bpm,
i.timeSigNumerator,
i.timeSigDenominator,
i.ppqLoopStart,
i.ppqLoopEnd,
i.isLooping);
};

return tie (*this) == tie (other);
}

bool operator!= (const CurrentPositionInfo& other) const noexcept
{
return ! operator== (other);
}

void resetToDefault()
{
*this = CurrentPositionInfo{};
}
};

//==============================================================================
/** Fills-in the given structure with details about the transport's
position at the start of the current processing block. If this method returns
false then the current play head position is not available and the given
structure will be undefined.
You can ONLY call this from your processBlock() method! Calling it at other
times will produce undefined behaviour, as the host may not have any context
in which a time would make sense, and some hosts will almost certainly have
multithreading issues if it's not called on the audio thread.
*/
virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0;

/** Returns true if this object can control the transport. */
virtual bool canControlTransport() { return false; }

/** Starts or stops the audio. */
virtual void transportPlay (bool shouldStartPlaying) { ignoreUnused (shouldStartPlaying); }

/** Starts or stops recording the audio. */
virtual void transportRecord (bool shouldStartRecording) { ignoreUnused (shouldStartRecording); }

/** Rewinds the audio. */
virtual void transportRewind() {}
};

} // namespace juce
Expand Up @@ -29,7 +29,7 @@ AudioChannelSet::AudioChannelSet (uint32 c) : channels (static_cast<int64> (c))
{
}

AudioChannelSet::AudioChannelSet (const Array<ChannelType>& c)
AudioChannelSet::AudioChannelSet (const std::initializer_list<ChannelType>& c)
{
for (auto channel : c)
addChannel (channel);
Expand Down Expand Up @@ -339,6 +339,8 @@ String AudioChannelSet::getDescription() const

if (*this == create5point0()) return "5.0 Surround";
if (*this == create5point1()) return "5.1 Surround";
if (*this == create5point1point2()) return "5.1.2 Surround";
if (*this == create5point1point4()) return "5.1.4 Surround";
if (*this == create6point0()) return "6.0 Surround";
if (*this == create6point1()) return "6.1 Surround";
if (*this == create6point0Music()) return "6.0 (Music) Surround";
Expand All @@ -348,7 +350,11 @@ String AudioChannelSet::getDescription() const
if (*this == create7point0SDDS()) return "7.0 Surround SDDS";
if (*this == create7point1SDDS()) return "7.1 Surround SDDS";
if (*this == create7point0point2()) return "7.0.2 Surround";
if (*this == create7point0point4()) return "7.0.4 Surround";
if (*this == create7point1point2()) return "7.1.2 Surround";
if (*this == create7point1point4()) return "7.1.4 Surround";
if (*this == create7point1point6()) return "7.1.6 Surround";
if (*this == create9point1point6()) return "9.1.6 Surround";

if (*this == quadraphonic()) return "Quadraphonic";
if (*this == pentagonal()) return "Pentagonal";
Expand Down Expand Up @@ -442,29 +448,33 @@ void AudioChannelSet::removeChannel (ChannelType newChannel)
}

AudioChannelSet AudioChannelSet::disabled() { return {}; }
AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); }
AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); }
AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); }
AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); }
AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); }
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); }
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
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::mono() { return AudioChannelSet ({ centre }); }
AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ({ left, right }); }
AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ({ left, right, centre }); }
AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ({ left, right, surround }); }
AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ({ left, right, centre, surround }); }
AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround }); }
AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround }); }
AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, centreSurround }); }
AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, centreSurround }); }
AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ({ left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); }
AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ({ left, right, LFE, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); }
AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); }
AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre }); }
AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); }
AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre }); }
AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ({ left, right, leftSurround, rightSurround }); }
AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ({ left, right, centre, leftSurroundRear, rightSurroundRear }); }
AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ({ left, right, centre, centreSurround, leftSurroundRear, rightSurroundRear }); }
AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, centreSurround, wideLeft, wideRight }); }
AudioChannelSet AudioChannelSet::create5point1point2() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topSideLeft, topSideRight }); }
AudioChannelSet AudioChannelSet::create5point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); }
AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); }
AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); }
AudioChannelSet AudioChannelSet::create7point0point4() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); }
AudioChannelSet AudioChannelSet::create7point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); }
AudioChannelSet AudioChannelSet::create7point1point6() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); }
AudioChannelSet AudioChannelSet::create9point1point6() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); }

AudioChannelSet AudioChannelSet::ambisonic (int order)
{
Expand Down Expand Up @@ -534,49 +544,55 @@ Array<AudioChannelSet> AudioChannelSet::channelSetsWithNumberOfChannels (int num
{
retval.add (AudioChannelSet::discreteChannels (numChannels));

if (numChannels == 1)
retval.addArray ([numChannels]() -> Array<AudioChannelSet>
{
retval.add (AudioChannelSet::mono());
}
else if (numChannels == 2)
{
retval.add (AudioChannelSet::stereo());
}
else if (numChannels == 3)
{
retval.add (AudioChannelSet::createLCR());
retval.add (AudioChannelSet::createLRS());
}
else if (numChannels == 4)
{
retval.add (AudioChannelSet::quadraphonic());
retval.add (AudioChannelSet::createLCRS());
}
else if (numChannels == 5)
{
retval.add (AudioChannelSet::create5point0());
retval.add (AudioChannelSet::pentagonal());
}
else if (numChannels == 6)
{
retval.add (AudioChannelSet::create5point1());
retval.add (AudioChannelSet::create6point0());
retval.add (AudioChannelSet::create6point0Music());
retval.add (AudioChannelSet::hexagonal());
}
else if (numChannels == 7)
{
retval.add (AudioChannelSet::create7point0());
retval.add (AudioChannelSet::create7point0SDDS());
retval.add (AudioChannelSet::create6point1());
retval.add (AudioChannelSet::create6point1Music());
}
else if (numChannels == 8)
{
retval.add (AudioChannelSet::create7point1());
retval.add (AudioChannelSet::create7point1SDDS());
retval.add (AudioChannelSet::octagonal());
}
switch (numChannels)
{
case 1:
return { AudioChannelSet::mono() };
case 2:
return { AudioChannelSet::stereo() };
case 3:
return { AudioChannelSet::createLCR(),
AudioChannelSet::createLRS() };
case 4:
return { AudioChannelSet::quadraphonic(),
AudioChannelSet::createLCRS() };
case 5:
return { AudioChannelSet::create5point0(),
AudioChannelSet::pentagonal() };
case 6:
return { AudioChannelSet::create5point1(),
AudioChannelSet::create6point0(),
AudioChannelSet::create6point0Music(),
AudioChannelSet::hexagonal() };
case 7:
return { AudioChannelSet::create7point0(),
AudioChannelSet::create7point0SDDS(),
AudioChannelSet::create6point1(),
AudioChannelSet::create6point1Music() };
case 8:
return { AudioChannelSet::create7point1(),
AudioChannelSet::create7point1SDDS(),
AudioChannelSet::octagonal(),
AudioChannelSet::create5point1point2() };
case 9:
return { AudioChannelSet::create7point0point2() };
case 10:
return { AudioChannelSet::create5point1point4(),
AudioChannelSet::create7point1point2() };
case 11:
return { AudioChannelSet::create7point0point4() };
case 12:
return { AudioChannelSet::create7point1point4() };
case 14:
return { AudioChannelSet::create7point1point6() };
case 16:
return { AudioChannelSet::create9point1point6() };
}

return {};
}());

auto order = getAmbisonicOrderForNumChannels (numChannels);
if (order >= 0)
Expand Down
Expand Up @@ -196,6 +196,18 @@ class JUCE_API AudioChannelSet
*/
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS();

/** Creates a set for a 5.1.2 surround setup (left, right, centre, LFE, leftSurround, rightSurround, topSideLeft, topSideRight).
Is equivalent to: kAudioChannelLayoutTag_Atmos_5_1_2 (CoreAudio).
*/
static AudioChannelSet JUCE_CALLTYPE create5point1point2();

/** Creates a set for a 5.1.4 surround setup (left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight).
Is equivalent to: kAudioChannelLayoutTag_Atmos_5_1_4 (CoreAudio).
*/
static AudioChannelSet JUCE_CALLTYPE create5point1point4();

/** Creates a set for Dolby Atmos 7.0.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight).
Is equivalent to: n/a (VST), AAX_eStemFormat_7_0_2 (AAX), n/a (CoreAudio)
Expand All @@ -204,7 +216,7 @@ class JUCE_API AudioChannelSet

/** Creates a set for Dolby Atmos 7.1.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE, topSideLeft, topSideRight).
Is equivalent to: k71_2 (VST), AAX_eStemFormat_7_1_2 (AAX), n/a (CoreAudio)
Is equivalent to: k71_2 (VST), AAX_eStemFormat_7_1_2 (AAX), kAudioChannelLayoutTag_Atmos_7_1_2 (CoreAudio)
*/
static AudioChannelSet JUCE_CALLTYPE create7point1point2();

Expand All @@ -216,10 +228,21 @@ class JUCE_API AudioChannelSet

/** 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)
Is equivalent to: k71_4 (VST), n/a (AAX), kAudioChannelLayoutTag_Atmos_7_1_4 (CoreAudio)
*/
static AudioChannelSet JUCE_CALLTYPE create7point1point4();

/** Creates a set for Dolby Atmos 7.1.6 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight).
Is equivalent to: k71_6 (VST), n/a (AAX), n/a (CoreAudio)
*/
static AudioChannelSet JUCE_CALLTYPE create7point1point6();

/** Creates a set for a 9.1.6 surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight).
Is equivalent to: kAudioChannelLayoutTag_Atmos_9_1_6 (CoreAudio).
*/
static AudioChannelSet JUCE_CALLTYPE create9point1point6();

//==============================================================================
/** Creates a set for quadraphonic surround setup (left, right, leftSurround, rightSurround)
Expand Down Expand Up @@ -318,8 +341,8 @@ class JUCE_API AudioChannelSet

//==============================================================================
// Used by Dolby Atmos 7.0.2 and 7.1.2
topSideLeft = 28, /**< Lts (AAX), Tsl (VST) channel for Dolby Atmos. */
topSideRight = 29, /**< Rts (AAX), Tsr (VST) channel for Dolby Atmos. */
topSideLeft = 28, /**< Lts (AAX), Tsl (VST), Ltm (AU) channel for Dolby Atmos. */
topSideRight = 29, /**< Rts (AAX), Tsr (VST), Rtm (AU) channel for Dolby Atmos. */

//==============================================================================
// Ambisonic ACN formats - all channels are SN3D normalised
Expand Down Expand Up @@ -487,7 +510,7 @@ class JUCE_API AudioChannelSet

//==============================================================================
explicit AudioChannelSet (uint32);
explicit AudioChannelSet (const Array<ChannelType>&);
explicit AudioChannelSet (const std::initializer_list<ChannelType>&);

//==============================================================================
static int JUCE_CALLTYPE getAmbisonicOrderForNumChannels (int);
Expand Down
Expand Up @@ -23,6 +23,9 @@
namespace juce
{

JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)

void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, int destBytesPerSample)
{
auto maxVal = (double) 0x7fff;
Expand Down Expand Up @@ -431,35 +434,22 @@ void AudioDataConverters::convertFormatToFloat (DataFormat sourceFormat, const v
//==============================================================================
void AudioDataConverters::interleaveSamples (const float** source, float* dest, int numSamples, int numChannels)
{
for (int chan = 0; chan < numChannels; ++chan)
{
auto i = chan;
auto src = source [chan];
using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;

for (int j = 0; j < numSamples; ++j)
{
dest [i] = src [j];
i += numChannels;
}
}
AudioData::interleaveSamples (AudioData::NonInterleavedSource<Format> { source, numChannels },
AudioData::InterleavedDest<Format> { dest, numChannels },
numSamples);
}

void AudioDataConverters::deinterleaveSamples (const float* source, float** dest, int numSamples, int numChannels)
{
for (int chan = 0; chan < numChannels; ++chan)
{
auto i = chan;
auto dst = dest [chan];
using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;

for (int j = 0; j < numSamples; ++j)
{
dst [j] = source [i];
i += numChannels;
}
}
AudioData::deinterleaveSamples (AudioData::InterleavedSource<Format> { source, numChannels },
AudioData::NonInterleavedDest<Format> { dest, numChannels },
numSamples);
}


//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
Expand All @@ -480,6 +470,7 @@ class AudioConversionTests : public UnitTest
test (unitTest, true, r);
}

JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6262)
static void test (UnitTest& unitTest, bool inPlace, Random& r)
{
const int numSamples = 2048;
Expand Down Expand Up @@ -537,6 +528,7 @@ class AudioConversionTests : public UnitTest
unitTest.expect (biggestDiff <= errorMargin);
}
}
JUCE_END_IGNORE_WARNINGS_MSVC
};

template <class F1, class E1, class FormatType>
Expand Down Expand Up @@ -586,11 +578,58 @@ class AudioConversionTests : public UnitTest
Test1 <AudioData::Int32>::test (*this, r);
beginTest ("Round-trip conversion: Float32");
Test1 <AudioData::Float32>::test (*this, r);

using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;

beginTest ("Interleaving");
{
constexpr auto numChannels = 4;
constexpr auto numSamples = 512;

AudioBuffer<float> sourceBuffer { numChannels, numSamples },
destBuffer { 1, numChannels * numSamples };

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
sourceBuffer.setSample (ch, i, r.nextFloat());

AudioData::interleaveSamples (AudioData::NonInterleavedSource<Format> { sourceBuffer.getArrayOfReadPointers(), numChannels },
AudioData::InterleavedDest<Format> { destBuffer.getWritePointer (0), numChannels },
numSamples);

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
expect (destBuffer.getSample (0, ch + (i * numChannels)) == sourceBuffer.getSample (ch, i));
}

beginTest ("Deinterleaving");
{
constexpr auto numChannels = 4;
constexpr auto numSamples = 512;

AudioBuffer<float> sourceBuffer { 1, numChannels * numSamples },
destBuffer { numChannels, numSamples };

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
sourceBuffer.setSample (0, ch + (i * numChannels), r.nextFloat());

AudioData::deinterleaveSamples (AudioData::InterleavedSource<Format> { sourceBuffer.getReadPointer (0), numChannels },
AudioData::NonInterleavedDest<Format> { destBuffer.getArrayOfWritePointers(), numChannels },
numSamples);

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
expect (sourceBuffer.getSample (0, ch + (i * numChannels)) == destBuffer.getSample (ch, i));
}
}
};

static AudioConversionTests audioConversionUnitTests;

#endif

JUCE_END_IGNORE_WARNINGS_MSVC
JUCE_END_IGNORE_WARNINGS_GCC_LIKE

} // namespace juce
Expand Up @@ -639,11 +639,152 @@ class JUCE_API AudioData

const int sourceChannels, destChannels;
};
};

//==============================================================================
/** A struct that contains a SampleFormat and Endianness to be used with the source and
destination types when calling the interleaveSamples() and deinterleaveSamples() helpers.
@see interleaveSamples, deinterleaveSamples
*/
template <typename DataFormatIn, typename EndiannessIn>
struct Format
{
using DataFormat = DataFormatIn;
using Endianness = EndiannessIn;
};

private:
template <bool IsInterleaved, bool IsConst, typename...>
struct ChannelDataSubtypes;

template <bool IsInterleaved, bool IsConst, typename DataFormat, typename Endianness>
struct ChannelDataSubtypes<IsInterleaved, IsConst, DataFormat, Endianness>
{
using ElementType = std::remove_pointer_t<decltype (DataFormat::data)>;
using ChannelType = std::conditional_t<IsConst, const ElementType*, ElementType*>;
using DataType = std::conditional_t<IsInterleaved, ChannelType, ChannelType*>;
using PointerType = Pointer<DataFormat,
Endianness,
std::conditional_t<IsInterleaved, Interleaved, NonInterleaved>,
std::conditional_t<IsConst, Const, NonConst>>;
};

template <bool IsInterleaved, bool IsConst, typename DataFormat, typename Endianness>
struct ChannelDataSubtypes<IsInterleaved, IsConst, Format<DataFormat, Endianness>>
{
using Subtypes = ChannelDataSubtypes<IsInterleaved, IsConst, DataFormat, Endianness>;
using DataType = typename Subtypes::DataType;
using PointerType = typename Subtypes::PointerType;
};

template <bool IsInterleaved, bool IsConst, typename... Format>
struct ChannelData
{
using Subtypes = ChannelDataSubtypes<IsInterleaved, IsConst, Format...>;
using DataType = typename Subtypes::DataType;
using PointerType = typename Subtypes::PointerType;

DataType data;
int channels;
};

public:
//==============================================================================
/** A sequence of interleaved samples used as the source for the deinterleaveSamples() method. */
template <typename... Format> using InterleavedSource = ChannelData<true, true, Format...>;
/** A sequence of interleaved samples used as the destination for the interleaveSamples() method. */
template <typename... Format> using InterleavedDest = ChannelData<true, false, Format...>;
/** A sequence of non-interleaved samples used as the source for the interleaveSamples() method. */
template <typename... Format> using NonInterleavedSource = ChannelData<false, true, Format...>;
/** A sequence of non-interleaved samples used as the destination for the deinterleaveSamples() method. */
template <typename... Format> using NonInterleavedDest = ChannelData<false, false, Format...>;

/** A helper function for converting a sequence of samples from a non-interleaved source
to an interleaved destination.
When calling this method you need to specify the source and destination data format and endianness
from the AudioData SampleFormat and Endianness types and provide the data and number of channels
for each. For example, to convert a floating-point stream of big endian samples to an interleaved,
native endian stream of 16-bit integer samples you would do the following:
@code
using SourceFormat = AudioData::Format<AudioData::Float32, AudioData::BigEndian>;
using DestFormat = AudioData::Format<AudioData::Int16, AudioData::NativeEndian>;
AudioData::interleaveSamples (AudioData::NonInterleavedSource<SourceFormat> { sourceData, numSourceChannels },
AudioData::InterleavedDest<DestFormat> { destData, numDestChannels },
numSamples);
@endcode
*/
template <typename... SourceFormat, typename... DestFormat>
static void interleaveSamples (NonInterleavedSource<SourceFormat...> source,
InterleavedDest<DestFormat...> dest,
int numSamples)
{
using SourceType = typename decltype (source)::PointerType;
using DestType = typename decltype (dest) ::PointerType;

for (int i = 0; i < dest.channels; ++i)
{
const DestType destType (addBytesToPointer (dest.data, i * DestType::getBytesPerSample()), dest.channels);

if (i < source.channels)
{
if (*source.data != nullptr)
{
destType.convertSamples (SourceType { *source.data }, numSamples);
++source.data;
}
}
else
{
destType.clearSamples (numSamples);
}
}
}

/** A helper function for converting a sequence of samples from an interleaved source
to a non-interleaved destination.
When calling this method you need to specify the source and destination data format and endianness
from the AudioData SampleFormat and Endianness types and provide the data and number of channels
for each. For example, to convert a floating-point stream of big endian samples to an non-interleaved,
native endian stream of 16-bit integer samples you would do the following:
@code
using SourceFormat = AudioData::Format<AudioData::Float32, AudioData::BigEndian>;
using DestFormat = AudioData::Format<AudioData::Int16, AudioData::NativeEndian>;
AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { sourceData, numSourceChannels },
AudioData::NonInterleavedDest<DestFormat> { destData, numDestChannels },
numSamples);
@endcode
*/
template <typename... SourceFormat, typename... DestFormat>
static void deinterleaveSamples (InterleavedSource<SourceFormat...> source,
NonInterleavedDest<DestFormat...> dest,
int numSamples)
{
using SourceType = typename decltype (source)::PointerType;
using DestType = typename decltype (dest) ::PointerType;

for (int i = 0; i < dest.channels; ++i)
{
if (auto* targetChan = dest.data[i])
{
const DestType destType (targetChan);

if (i < source.channels)
destType.convertSamples (SourceType (addBytesToPointer (source.data, i * SourceType::getBytesPerSample()), source.channels), numSamples);
else
destType.clearSamples (numSamples);
}
}
}
};

//==============================================================================
#ifndef DOXYGEN
/**
A set of routines to convert buffers of 32-bit floating point data to and from
various integer formats.
Expand All @@ -653,7 +794,7 @@ class JUCE_API AudioData
@tags{Audio}
*/
class JUCE_API AudioDataConverters
class [[deprecated]] JUCE_API AudioDataConverters
{
public:
//==============================================================================
Expand Down Expand Up @@ -710,7 +851,7 @@ class JUCE_API AudioDataConverters

private:
AudioDataConverters();
JUCE_DECLARE_NON_COPYABLE (AudioDataConverters)
};
#endif

} // namespace juce
Expand Up @@ -23,8 +23,8 @@
namespace juce
{

AudioProcessLoadMeasurer::AudioProcessLoadMeasurer() {}
AudioProcessLoadMeasurer::~AudioProcessLoadMeasurer() {}
AudioProcessLoadMeasurer::AudioProcessLoadMeasurer() = default;
AudioProcessLoadMeasurer::~AudioProcessLoadMeasurer() = default;

void AudioProcessLoadMeasurer::reset()
{
Expand All @@ -33,43 +33,60 @@ void AudioProcessLoadMeasurer::reset()

void AudioProcessLoadMeasurer::reset (double sampleRate, int blockSize)
{
cpuUsageMs = 0;
cpuUsageProportion = 0;
xruns = 0;

samplesPerBlock = blockSize;

if (sampleRate > 0.0 && blockSize > 0)
{
msPerBlock = 1000.0 * blockSize / sampleRate;
timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0;
msPerSample = 1000.0 / sampleRate;
timeToCpuScale = (msPerSample > 0.0) ? (1.0 / msPerSample) : 0.0;
}
else
{
msPerBlock = 0;
msPerSample = 0;
timeToCpuScale = 0;
}
}

void AudioProcessLoadMeasurer::registerBlockRenderTime (double milliseconds)
{
const double filterAmount = 0.2;
cpuUsageMs += filterAmount * (milliseconds - cpuUsageMs);
registerRenderTime (milliseconds, samplesPerBlock);
}

void AudioProcessLoadMeasurer::registerRenderTime (double milliseconds, int numSamples)
{
const auto maxMilliseconds = numSamples * msPerSample;
const auto usedProportion = milliseconds / maxMilliseconds;
const auto filterAmount = 0.2;
cpuUsageProportion += filterAmount * (usedProportion - cpuUsageProportion);

if (milliseconds > msPerBlock)
if (milliseconds > maxMilliseconds)
++xruns;
}

double AudioProcessLoadMeasurer::getLoadAsProportion() const { return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs); }
double AudioProcessLoadMeasurer::getLoadAsProportion() const { return jlimit (0.0, 1.0, cpuUsageProportion); }
double AudioProcessLoadMeasurer::getLoadAsPercentage() const { return 100.0 * getLoadAsProportion(); }

int AudioProcessLoadMeasurer::getXRunCount() const { return xruns; }

AudioProcessLoadMeasurer::ScopedTimer::ScopedTimer (AudioProcessLoadMeasurer& p)
: owner (p), startTime (Time::getMillisecondCounterHiRes())
: ScopedTimer (p, p.samplesPerBlock)
{
}

AudioProcessLoadMeasurer::ScopedTimer::ScopedTimer (AudioProcessLoadMeasurer& p, int numSamplesInBlock)
: owner (p), startTime (Time::getMillisecondCounterHiRes()), samplesInBlock (numSamplesInBlock)
{
// numSamplesInBlock should never be zero. Did you remember to call AudioProcessLoadMeasurer::reset(),
// passing the expected samples per block?
jassert (numSamplesInBlock);
}

AudioProcessLoadMeasurer::ScopedTimer::~ScopedTimer()
{
owner.registerBlockRenderTime (Time::getMillisecondCounterHiRes() - startTime);
owner.registerRenderTime (Time::getMillisecondCounterHiRes() - startTime, samplesInBlock);
}

} // namespace juce
Expand Up @@ -72,11 +72,13 @@ class JUCE_API AudioProcessLoadMeasurer
struct JUCE_API ScopedTimer
{
ScopedTimer (AudioProcessLoadMeasurer&);
ScopedTimer (AudioProcessLoadMeasurer&, int numSamplesInBlock);
~ScopedTimer();

private:
AudioProcessLoadMeasurer& owner;
double startTime;
int samplesInBlock;

JUCE_DECLARE_NON_COPYABLE (ScopedTimer)
};
Expand All @@ -87,9 +89,15 @@ class JUCE_API AudioProcessLoadMeasurer
*/
void registerBlockRenderTime (double millisecondsTaken);

/** Can be called manually to add the time of a callback to the stats.
Normally you probably would never call this - it's simpler and more robust to
use a ScopedTimer to measure the time using an RAII pattern.
*/
void registerRenderTime (double millisecondsTaken, int numSamples);

private:
double cpuUsageMs = 0, timeToCpuScale = 0, msPerBlock = 0;
int xruns = 0;
double cpuUsageProportion = 0, timeToCpuScale = 0, msPerSample = 0;
int xruns = 0, samplesPerBlock = 0;
};


Expand Down