| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| 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 8683dc728..94f6bf569 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_plugin_client/utility/juce_CheckSettingMacros.h b/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h | ||
| index 6bea84307..baaa59f06 100644 | ||
| --- a/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h | ||
| +++ b/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h | ||
| @@ -73,11 +73,6 @@ | ||
| #define JucePlugin_Build_RTAS 0 | ||
| #endif | ||
|
|
||
| -#if ! (defined (_MSC_VER) || defined (__APPLE_CPP__) || defined (__APPLE_CC__) || defined (LINUX) || defined (__linux__)) | ||
| - #undef JucePlugin_Build_VST3 | ||
| - #define JucePlugin_Build_VST3 0 | ||
| -#endif | ||
| - | ||
| //============================================================================== | ||
| #if JucePlugin_Build_LV2 && ! defined (JucePlugin_LV2URI) | ||
| #error "You need to define the JucePlugin_LV2URI value!" | ||
| diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp | ||
| index 620ba9874..d9359b736 100644 | ||
| --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp | ||
| +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp | ||
| @@ -62,9 +62,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_core/threads/juce_WaitableEvent.h b/modules/juce_core/threads/juce_WaitableEvent.h | ||
| index 52269f706..670903653 100644 | ||
| --- a/modules/juce_core/threads/juce_WaitableEvent.h | ||
| +++ b/modules/juce_core/threads/juce_WaitableEvent.h | ||
| @@ -20,6 +20,10 @@ | ||
| ============================================================================== | ||
| */ | ||
|
|
||
| +#if JUCE_MINGW && !defined(_GLIBCXX_HAS_GTHREADS) | ||
| +#include "mingw-std-threads/mingw.condition_variable.h" | ||
| +#endif | ||
| + | ||
| namespace juce | ||
| { | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| 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 | ||
| --- 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 | ||
|
|
||
| -#include <ladspa.h> | ||
| +#include "ladspa.h" | ||
|
|
||
| namespace juce | ||
| { |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h | ||
| index 082a5697a..c79ca18ea 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() | ||
|
|
||
| auto localSymbol = (void*) juce_getExecutableFile; | ||
| dladdr (localSymbol, &exeInfo); | ||
| - return CharPointer_UTF8 (exeInfo.dli_fname); | ||
| + | ||
| + const CharPointer_UTF8 filename (exeInfo.dli_fname); | ||
| + | ||
| + // if the filename is absolute simply return it | ||
| + if (File::isAbsolutePath (filename)) | ||
| + return filename; | ||
| + | ||
| + // if the filename is relative construct from CWD | ||
| + if (filename[0] == '.') | ||
| + return File::getCurrentWorkingDirectory().getChildFile (filename).getFullPathName(); | ||
| + | ||
| + // filename is abstract, look up in PATH | ||
| + if (const char* const envpath = ::getenv ("PATH")) | ||
| + { | ||
| + StringArray paths (StringArray::fromTokens (envpath, ":", "")); | ||
| + | ||
| + for (int i=paths.size(); --i>=0;) | ||
| + { | ||
| + const File filepath (File (paths[i]).getChildFile (filename)); | ||
| + | ||
| + if (filepath.existsAsFile()) | ||
| + return filepath.getFullPathName(); | ||
| + } | ||
| + } | ||
| + | ||
| + // if we reach this, we failed to find ourselves... | ||
| + jassertfalse; | ||
| + return filename; | ||
| } | ||
| }; | ||
|
|
||
| static String filename = DLAddrReader::getFilename(); | ||
| - return File::getCurrentWorkingDirectory().getChildFile (filename); | ||
| + return filename; | ||
| } | ||
|
|
||
| //============================================================================== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| diff --git a/modules/juce_core/native/juce_linux_Files.cpp b/modules/juce_core/native/juce_linux_Files.cpp | ||
| index d2a302e3e..3dc4602ce 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) | ||
|
|
||
| const char* const argv[4] = { "/bin/sh", "-c", cmdString.toUTF8(), nullptr }; | ||
|
|
||
| - auto cpid = fork(); | ||
| +#if JUCE_USE_VFORK | ||
| + const auto cpid = vfork(); | ||
| +#else | ||
| + const auto cpid = fork(); | ||
| +#endif | ||
|
|
||
| if (cpid == 0) | ||
| { | ||
| +#if ! JUCE_USE_VFORK | ||
| setsid(); | ||
| +#endif | ||
|
|
||
| // Child process | ||
| - execve (argv[0], (char**) argv, environ); | ||
| - exit (0); | ||
| + if (execvp (argv[0], (char**) argv) < 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 | ||
| --- 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) | ||
| { | ||
| + const char* const argv[4] = { "/bin/sh", "-c", pathAndArguments.toUTF8(), nullptr }; | ||
| + | ||
| +#if JUCE_USE_VFORK | ||
| + const auto cpid = vfork(); | ||
| +#else | ||
| auto cpid = fork(); | ||
| +#endif | ||
|
|
||
| if (cpid == 0) | ||
| { | ||
| - const char* const argv[4] = { "/bin/sh", "-c", pathAndArguments.toUTF8(), nullptr }; | ||
| - | ||
| // Child process | ||
| - if (execve (argv[0], (char**) argv, nullptr) < 0) | ||
| - exit (0); | ||
| - } | ||
| - else | ||
| - { | ||
| - if (cpid < 0) | ||
| - return false; | ||
| + if (execvp (argv[0], (char**) argv) < 0) | ||
| + _exit (0); | ||
| } | ||
|
|
||
| - return true; | ||
| + return cpid >= 0; | ||
| } | ||
| #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 | ||
| --- a/modules/juce_core/native/juce_posix_SharedCode.h | ||
| +++ b/modules/juce_core/native/juce_posix_SharedCode.h | ||
| @@ -1104,7 +1104,18 @@ public: | ||
|
|
||
| if (pipe (pipeHandles) == 0) | ||
| { | ||
| - auto result = fork(); | ||
| + Array<char*> argv; | ||
| + for (auto& arg : arguments) | ||
| + if (arg.isNotEmpty()) | ||
| + argv.add (const_cast<char*> (arg.toRawUTF8())); | ||
| + | ||
| + argv.add (nullptr); | ||
| + | ||
| +#if JUCE_USE_VFORK | ||
| + const pid_t result = vfork(); | ||
| +#else | ||
| + const pid_t result = fork(); | ||
| +#endif | ||
|
|
||
| if (result < 0) | ||
| { | ||
| @@ -1113,6 +1124,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: | ||
| dup2 (open ("/dev/null", O_WRONLY), STDERR_FILENO); | ||
|
|
||
| close (pipeHandles[1]); | ||
| +#endif | ||
|
|
||
| - Array<char*> argv; | ||
| - | ||
| - for (auto& arg : arguments) | ||
| - if (arg.isNotEmpty()) | ||
| - argv.add (const_cast<char*> (arg.toRawUTF8())); | ||
| - | ||
| - argv.add (nullptr); | ||
| - | ||
| - execvp (exe.toRawUTF8(), argv.getRawDataPointer()); | ||
| - _exit (-1); | ||
| + if (execvp (exe.toRawUTF8(), argv.getRawDataPointer()) < 0) | ||
| + _exit (-1); | ||
| } | ||
| else | ||
| { |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h | ||
| index ad46cf390..13724ba7c 100644 | ||
| --- a/modules/juce_core/native/juce_posix_SharedCode.h | ||
| +++ b/modules/juce_core/native/juce_posix_SharedCode.h | ||
| @@ -1239,6 +1239,11 @@ public: | ||
| return 0; | ||
| } | ||
|
|
||
| + int getPID() const noexcept | ||
| + { | ||
| + return childPID; | ||
| + } | ||
| + | ||
| int childPID = 0; | ||
| 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 | ||
| --- a/modules/juce_core/native/juce_win32_Threads.cpp | ||
| +++ b/modules/juce_core/native/juce_win32_Threads.cpp | ||
| @@ -477,6 +477,11 @@ public: | ||
| return (uint32) exitCode; | ||
| } | ||
|
|
||
| + int getPID() const noexcept | ||
| + { | ||
| + return 0; | ||
| + } | ||
| + | ||
| bool ok; | ||
|
|
||
| private: | ||
| diff --git a/modules/juce_core/threads/juce_ChildProcess.cpp b/modules/juce_core/threads/juce_ChildProcess.cpp | ||
| index 3b284c25a..31e9c8d94 100644 | ||
| --- a/modules/juce_core/threads/juce_ChildProcess.cpp | ||
| +++ b/modules/juce_core/threads/juce_ChildProcess.cpp | ||
| @@ -81,6 +81,11 @@ String ChildProcess::readAllProcessOutput() | ||
| } | ||
|
|
||
|
|
||
| +uint32 ChildProcess::getPID() const noexcept | ||
| +{ | ||
| + return activeProcess != nullptr ? activeProcess->getPID() : 0; | ||
| +} | ||
| + | ||
| //============================================================================== | ||
| //============================================================================== | ||
| #if JUCE_UNIT_TESTS | ||
| diff --git a/modules/juce_core/threads/juce_ChildProcess.h b/modules/juce_core/threads/juce_ChildProcess.h | ||
| index 47a26281b..74dbb11ab 100644 | ||
| --- a/modules/juce_core/threads/juce_ChildProcess.h | ||
| +++ b/modules/juce_core/threads/juce_ChildProcess.h | ||
| @@ -101,6 +101,8 @@ public: | ||
| */ | ||
| bool kill(); | ||
|
|
||
| + uint32 getPID() const noexcept; | ||
| + | ||
| private: | ||
| //============================================================================== | ||
| class ActiveProcess; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| diff --git a/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp b/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp | ||
| index 746686bf7..2c8cb3a2b 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 @@ | ||
| namespace juce | ||
| { | ||
|
|
||
| +#if JUCE_MODAL_LOOPS_PERMITTED | ||
| static bool exeIsAvailable (String executable) | ||
| { | ||
| ChildProcess child; | ||
| @@ -245,10 +246,11 @@ private: | ||
|
|
||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Native) | ||
| }; | ||
| +#endif | ||
|
|
||
| bool FileChooser::isPlatformDialogAvailable() | ||
| { | ||
| - #if JUCE_DISABLE_NATIVE_FILECHOOSERS | ||
| + #if JUCE_DISABLE_NATIVE_FILECHOOSERS || ! JUCE_MODAL_LOOPS_PERMITTED | ||
| return false; | ||
| #else | ||
| static bool canUseNativeBox = exeIsAvailable ("zenity") || exeIsAvailable ("kdialog"); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| diff --git a/modules/juce_gui_basics/windows/juce_DialogWindow.cpp b/modules/juce_gui_basics/windows/juce_DialogWindow.cpp | ||
| index ea2675d59..92bf09e16 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, | ||
| Colour backgroundColour, | ||
| const bool escapeKeyTriggersCloseButton, | ||
| const bool resizable, | ||
| - const bool useBottomRightCornerResizer) | ||
| + const bool useBottomRightCornerResizer, | ||
| + const bool useNativeTitleBar) | ||
| { | ||
| LaunchOptions o; | ||
| o.dialogTitle = dialogTitle; | ||
| @@ -139,9 +140,9 @@ void DialogWindow::showDialog (const String& dialogTitle, | ||
| o.componentToCentreAround = componentToCentreAround; | ||
| o.dialogBackgroundColour = backgroundColour; | ||
| o.escapeKeyTriggersCloseButton = escapeKeyTriggersCloseButton; | ||
| - o.useNativeTitleBar = false; | ||
| o.resizable = resizable; | ||
| o.useBottomRightCornerResizer = useBottomRightCornerResizer; | ||
| + o.useNativeTitleBar = useNativeTitleBar; | ||
|
|
||
| o.launchAsync(); | ||
| } | ||
| @@ -153,7 +154,8 @@ int DialogWindow::showModalDialog (const String& dialogTitle, | ||
| Colour backgroundColour, | ||
| const bool escapeKeyTriggersCloseButton, | ||
| const bool resizable, | ||
| - const bool useBottomRightCornerResizer) | ||
| + const bool useBottomRightCornerResizer, | ||
| + const bool useNativeTitleBar) | ||
| { | ||
| LaunchOptions o; | ||
| o.dialogTitle = dialogTitle; | ||
| @@ -161,9 +163,9 @@ int DialogWindow::showModalDialog (const String& dialogTitle, | ||
| o.componentToCentreAround = componentToCentreAround; | ||
| o.dialogBackgroundColour = backgroundColour; | ||
| o.escapeKeyTriggersCloseButton = escapeKeyTriggersCloseButton; | ||
| - o.useNativeTitleBar = false; | ||
| o.resizable = resizable; | ||
| o.useBottomRightCornerResizer = useBottomRightCornerResizer; | ||
| + o.useNativeTitleBar = useNativeTitleBar; | ||
|
|
||
| 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 | ||
| --- a/modules/juce_gui_basics/windows/juce_DialogWindow.h | ||
| +++ b/modules/juce_gui_basics/windows/juce_DialogWindow.h | ||
| @@ -193,7 +193,8 @@ public: | ||
| Colour backgroundColour, | ||
| bool escapeKeyTriggersCloseButton, | ||
| bool shouldBeResizable = false, | ||
| - bool useBottomRightCornerResizer = false); | ||
| + bool useBottomRightCornerResizer = false, | ||
| + bool useNativeTitleBar = false); | ||
|
|
||
| #if JUCE_MODAL_LOOPS_PERMITTED || DOXYGEN | ||
| /** Easy way of quickly showing a dialog box containing a given component. | ||
| @@ -239,7 +240,8 @@ public: | ||
| Colour backgroundColour, | ||
| bool escapeKeyTriggersCloseButton, | ||
| bool shouldBeResizable = false, | ||
| - bool useBottomRightCornerResizer = false); | ||
| + bool useBottomRightCornerResizer = false, | ||
| + bool useNativeTitleBar = false); | ||
| #endif | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| 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 | ||
| --- 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 | ||
|
|
||
| if (atoms.windowType != None) | ||
| { | ||
| - auto hint = (styleFlags & ComponentPeer::windowIsTemporary) != 0 | ||
| - || ((styleFlags & ComponentPeer::windowHasDropShadow) == 0 && Desktop::canUseSemiTransparentWindows()) | ||
| - ? XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_COMBO") | ||
| - : XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_NORMAL"); | ||
| + Atom hint = None; | ||
| + | ||
| + if (styleFlags & ComponentPeer::windowIsTemporary) | ||
| + hint = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"); | ||
| + else if ((styleFlags & ComponentPeer::windowHasDropShadow) == 0 && Desktop::canUseSemiTransparentWindows()) | ||
| + hint = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_COMBO"); | ||
| + else | ||
| + hint = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_NORMAL"); | ||
|
|
||
| if (hint != None) | ||
| xchangeProperty (windowH, atoms.windowType, XA_ATOM, 32, &hint, 1); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h | ||
| index 13724ba7c..f8892081c 100644 | ||
| --- a/modules/juce_core/native/juce_posix_SharedCode.h | ||
| +++ b/modules/juce_core/native/juce_posix_SharedCode.h | ||
| @@ -989,7 +989,11 @@ bool Thread::setThreadPriority (void* handle, int priority) | ||
| if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) != 0) | ||
| return false; | ||
|
|
||
| + #if JUCE_LINUX | ||
| + policy = priority < 9 ? SCHED_OTHER : SCHED_RR; | ||
| + #else | ||
| policy = priority == 0 ? SCHED_OTHER : SCHED_RR; | ||
| + #endif | ||
|
|
||
| const int minPriority = sched_get_priority_min (policy); | ||
| const int maxPriority = sched_get_priority_max (policy); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h | ||
| index ae60fde15..dbad562ef 100644 | ||
| --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h | ||
| +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h | ||
| @@ -1116,6 +1116,11 @@ public: | ||
| /** This method is called when the layout of the audio processor changes. */ | ||
| virtual void processorLayoutsChanged(); | ||
|
|
||
| + //============================================================================== | ||
| + /** LV2 specific calls, saving/restore as string. */ | ||
| + virtual String getStateInformationString () { return String(); } | ||
| + virtual void setStateInformationString (const String&) {} | ||
| + | ||
| //============================================================================== | ||
| /** Adds a listener that will be called when an aspect of this processor changes. */ | ||
| virtual void addListener (AudioProcessorListener* newListener); | ||
| @@ -1200,6 +1205,7 @@ public: | ||
| wrapperType_AudioUnitv3, | ||
| wrapperType_RTAS, | ||
| wrapperType_AAX, | ||
| + wrapperType_LV2, | ||
| wrapperType_Standalone, | ||
| wrapperType_Unity | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| 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 | ||
| --- 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: | ||
| // You must at least have some channels | ||
| jassert (processor->isMidiEffect() || (maxNumInChannels > 0 || maxNumOutChannels > 0)); | ||
|
|
||
| - if (processor->isMidiEffect()) | ||
| - maxNumInChannels = maxNumOutChannels = 2; | ||
| - | ||
| #ifdef JucePlugin_PreferredChannelConfigurations | ||
| processor->setPlayConfigDetails (maxNumInChannels, maxNumOutChannels, 44100.0, 1024); | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| 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 | ||
| --- 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: | ||
|
|
||
| pointer_sized_int handleGetPlugInName (VstOpCodeArguments args) | ||
| { | ||
| - String (JucePlugin_Name).copyToUTF8 ((char*) args.ptr, 64 + 1); | ||
| + String (processor->getName()).copyToUTF8 ((char*) args.ptr, 64 + 1); | ||
| return 1; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| 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 ebc9325ca..cabbbcf13 100644 | ||
| --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp | ||
| +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp | ||
| @@ -203,11 +203,11 @@ struct SharedMessageThread : public Thread | ||
| void run() override | ||
| { | ||
| initialiseJuce_GUI(); | ||
| - initialised = true; | ||
|
|
||
| MessageManager::getInstance()->setCurrentThreadAsMessageThread(); | ||
|
|
||
| XWindowSystem::getInstance(); | ||
| + initialised = true; | ||
|
|
||
| while ((! threadShouldExit()) && MessageManager::getInstance()->runDispatchLoopUntil (250)) | ||
| {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| diff --git a/modules/juce_events/messages/juce_MessageManager.h b/modules/juce_events/messages/juce_MessageManager.h | ||
| index ae7231101..fff5b9794 100644 | ||
| --- a/modules/juce_events/messages/juce_MessageManager.h | ||
| +++ b/modules/juce_events/messages/juce_MessageManager.h | ||
| @@ -311,6 +311,7 @@ public: | ||
| // Internal methods - do not use! | ||
| void deliverBroadcastMessage (const String&); | ||
| ~MessageManager() noexcept; | ||
| + static bool dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages); | ||
| #endif | ||
|
|
||
| private: | ||
| @@ -333,7 +334,6 @@ private: | ||
| static void* exitModalLoopCallback (void*); | ||
| static void doPlatformSpecificInitialisation(); | ||
| static void doPlatformSpecificShutdown(); | ||
| - static bool dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages); | ||
|
|
||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageManager) | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp | ||
| index 43ad88e1b..149154804 100644 | ||
| --- a/modules/juce_audio_processors/juce_audio_processors.cpp | ||
| +++ b/modules/juce_audio_processors/juce_audio_processors.cpp | ||
| @@ -47,7 +47,7 @@ | ||
| #endif | ||
| #endif | ||
|
|
||
| -#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && JUCE_LINUX | ||
| +#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && JUCE_LINUX && ! JUCE_AUDIOPROCESSOR_NO_GUI | ||
| #include <X11/Xlib.h> | ||
| #include <X11/Xutil.h> | ||
| #include <sys/utsname.h> | ||
| @@ -230,9 +230,11 @@ struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewCompone | ||
| #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" | ||
| diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp | ||
| index 040accf2e..df0b6c67b 100644 | ||
| --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp | ||
| +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp | ||
| @@ -51,12 +51,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 | ||
| @@ -826,6 +828,7 @@ void AudioProcessor::audioIOChanged (bool busNumberChanged, bool channelNumChang | ||
| processorLayoutsChanged(); | ||
| } | ||
|
|
||
| +#if ! JUCE_AUDIOPROCESSOR_NO_GUI | ||
| //============================================================================== | ||
| void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept | ||
| { | ||
| @@ -862,6 +865,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 f72a4ed3f..849b77d3c 100644 | ||
| --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h | ||
| +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h | ||
| @@ -926,6 +926,7 @@ public: | ||
| */ | ||
| virtual void setNonRealtime (bool isNonRealtime) noexcept; | ||
|
|
||
| + #if ! JUCE_AUDIOPROCESSOR_NO_GUI | ||
| //============================================================================== | ||
| /** Creates the processor's GUI. | ||
|
|
||
| @@ -975,6 +976,7 @@ public: | ||
| This may call createEditor() internally to create the component. | ||
| */ | ||
| AudioProcessorEditor* createEditorIfNeeded(); | ||
| + #endif | ||
|
|
||
| //============================================================================== | ||
| /** Returns the default number of steps for a parameter. | ||
| @@ -1191,9 +1193,11 @@ public: | ||
|
|
||
| virtual CurveData getResponseCurve (CurveData::Type /*curveType*/) const { return CurveData(); } | ||
|
|
||
| + #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 | ||
| @@ -1468,7 +1472,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 17c5af30c..3d4a0d428 100644 | ||
| --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp | ||
| +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp | ||
| @@ -1519,8 +1519,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 a60e67d84..17a121893 100644 | ||
| --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h | ||
| +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h | ||
| @@ -355,8 +355,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; | ||
| @@ -392,8 +394,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 { } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| diff --git a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp | ||
| index 7f7d766f8..c84c10d0b 100755 | ||
| --- a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp | ||
| +++ b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp | ||
| @@ -162,6 +162,7 @@ private: | ||
| void operator() (LPWSTR ptr) const noexcept { CoTaskMemFree (ptr); } | ||
| }; | ||
|
|
||
| + #if JUCE_MSVC | ||
| bool showDialog (IFileDialog& dialog, bool async) | ||
| { | ||
| FILEOPENDIALOGOPTIONS flags = {}; | ||
| @@ -371,6 +372,7 @@ private: | ||
|
|
||
| return result; | ||
| } | ||
| + #endif | ||
|
|
||
| Array<URL> openDialogPreVista (bool async) | ||
| { | ||
| @@ -480,11 +482,13 @@ private: | ||
|
|
||
| const Remover remover (*this); | ||
|
|
||
| + #if JUCE_MSVC | ||
| if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista | ||
| && customComponent == nullptr) | ||
| { | ||
| return openDialogVistaAndUp (async); | ||
| } | ||
| + #endif | ||
|
|
||
| return openDialogPreVista (async); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| 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 cabbbcf13..f722ab36c 100644 | ||
| --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp | ||
| +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp | ||
| @@ -488,7 +488,7 @@ public: | ||
|
|
||
| { | ||
| const int numChannels = jmax (numIn, numOut); | ||
| - AudioBuffer<FloatType> chans (tmpBuffers.channels, isMidiEffect ? 0 : numChannels, numSamples); | ||
| + juce::AudioBuffer<FloatType> chans (tmpBuffers.channels, isMidiEffect ? 0 : numChannels, numSamples); | ||
|
|
||
| if (isBypassed) | ||
| processor->processBlockBypassed (chans, midiEvents); | ||
| diff --git a/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h b/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h | ||
| index 4b36f6d64..61dbdeede 100644 | ||
| --- a/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h | ||
| +++ b/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h | ||
| @@ -23,6 +23,8 @@ | ||
| ============================================================================== | ||
| */ | ||
|
|
||
| +#pragma once | ||
| + | ||
| #include <juce_audio_plugin_client/juce_audio_plugin_client.h> | ||
| #include "juce_CreatePluginFilter.h" | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp | ||
| index c4404c637..fa8d3ccf5 100644 | ||
| --- a/modules/juce_gui_basics/components/juce_Component.cpp | ||
| +++ b/modules/juce_gui_basics/components/juce_Component.cpp | ||
| @@ -387,6 +387,10 @@ struct Component::ComponentHelpers | ||
| template <typename PointOrRect> | ||
| static PointOrRect convertCoordinate (const Component* target, const Component* source, PointOrRect p) | ||
| { | ||
| + float total_scaling = source->getTotalPixelScaling(); | ||
| + Component* top = nullptr; | ||
| + if (source) | ||
| + top = source->getTopLevelComponent(); | ||
| while (source != nullptr) | ||
| { | ||
| if (source == target) | ||
| @@ -395,6 +399,9 @@ struct Component::ComponentHelpers | ||
| if (source->isParentOf (target)) | ||
| return convertFromDistantParentSpace (source, *target, p); | ||
|
|
||
| + if (source == top) | ||
| + p /= total_scaling; | ||
| + | ||
| p = convertToParentSpace (*source, p); | ||
| source = source->getParentComponent(); | ||
| } | ||
| @@ -1390,13 +1397,14 @@ bool Component::reallyContains (Point<int> point, bool returnTrueIfWithinAChild) | ||
|
|
||
| Component* Component::getComponentAt (Point<int> position) | ||
| { | ||
| + Point<int> scale = (position.toFloat() * getPixelScaling()).roundToInt(); | ||
| if (flags.visibleFlag && ComponentHelpers::hitTest (*this, position)) | ||
| { | ||
| for (int i = childComponentList.size(); --i >= 0;) | ||
| { | ||
| auto* child = childComponentList.getUnchecked(i); | ||
|
|
||
| - child = child->getComponentAt (ComponentHelpers::convertFromParentSpace (*child, position)); | ||
| + child = child->getComponentAt (ComponentHelpers::convertFromParentSpace (*child, scale)); | ||
|
|
||
| if (child != nullptr) | ||
| return child; | ||
| diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h | ||
| index 6b2b0072b..ccb2681fa 100644 | ||
| --- a/modules/juce_gui_basics/components/juce_Component.h | ||
| +++ b/modules/juce_gui_basics/components/juce_Component.h | ||
| @@ -2284,6 +2284,17 @@ public: | ||
| */ | ||
| bool getViewportIgnoreDragFlag() const noexcept { return flags.viewportIgnoreDragFlag; } | ||
|
|
||
| + virtual float getPixelScaling() const { return 1.0f; } | ||
| + float getTotalPixelScaling() const { | ||
| + const Component* component = this; | ||
| + float pixel_scaling = 1.0f; | ||
| + while (component) { | ||
| + pixel_scaling *= component->getPixelScaling(); | ||
| + component = component->getParentComponent(); | ||
| + } | ||
| + return pixel_scaling; | ||
| + } | ||
| + | ||
| private: | ||
| //============================================================================== | ||
| friend class ComponentPeer; | ||
| diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp | ||
| index a8c2c283a..ddb15b88d 100644 | ||
| --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp | ||
| +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp | ||
| @@ -61,7 +61,7 @@ public: | ||
| { | ||
| if (auto* peer = comp.getPeer()) | ||
| { | ||
| - pos = peer->globalToLocal (pos); | ||
| + pos = peer->globalToLocal (pos) * comp.getTotalPixelScaling(); | ||
| auto& peerComp = peer->getComponent(); | ||
| return comp.getLocalPoint (&peerComp, ScalingHelpers::unscaledScreenPosToScaled (peerComp, pos)); | ||
| } | ||
| diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp | ||
| index 8d7febd4b..7ec8fbb00 100644 | ||
| --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp | ||
| +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp | ||
| @@ -474,7 +474,7 @@ bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info) | ||
| if (DragHelpers::isSuitableTarget (info, newTarget)) | ||
| { | ||
| dragAndDropTargetComponent = newTarget; | ||
| - auto pos = newTarget->getLocalPoint (&component, info.position); | ||
| + auto pos = newTarget->getLocalPoint (&component, info.position * newTarget->getTotalPixelScaling()); | ||
|
|
||
| if (DragHelpers::isFileDrag (info)) | ||
| dynamic_cast<FileDragAndDropTarget*> (newTarget)->fileDragEnter (info.files, pos.x, pos.y); | ||
| @@ -491,7 +491,7 @@ bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info) | ||
| if (! DragHelpers::isSuitableTarget (info, newTarget)) | ||
| return false; | ||
|
|
||
| - auto pos = newTarget->getLocalPoint (&component, info.position); | ||
| + auto pos = newTarget->getLocalPoint (&component, info.position * newTarget->getTotalPixelScaling()); | ||
|
|
||
| if (DragHelpers::isFileDrag (info)) | ||
| dynamic_cast<FileDragAndDropTarget*> (newTarget)->fileDragMove (info.files, pos.x, pos.y); | ||
| diff --git a/modules/juce_opengl/native/juce_OpenGLExtensions.h b/modules/juce_opengl/native/juce_OpenGLExtensions.h | ||
| index e7eab9dbf..d7039b144 100644 | ||
| --- a/modules/juce_opengl/native/juce_OpenGLExtensions.h | ||
| +++ b/modules/juce_opengl/native/juce_OpenGLExtensions.h | ||
| @@ -83,7 +83,13 @@ namespace juce | ||
| USE_FUNCTION (glCheckFramebufferStatus, GLenum, (GLenum p1), (p1))\ | ||
| USE_FUNCTION (glFramebufferTexture2D, void, (GLenum p1, GLenum p2, GLenum p3, GLuint p4, GLint p5), (p1, p2, p3, p4, p5))\ | ||
| USE_FUNCTION (glFramebufferRenderbuffer, void, (GLenum p1, GLenum p2, GLenum p3, GLuint p4), (p1, p2, p3, p4))\ | ||
| - USE_FUNCTION (glGetFramebufferAttachmentParameteriv, void, (GLenum p1, GLenum p2, GLenum p3, GLint* p4), (p1, p2, p3, p4)) | ||
| + USE_FUNCTION (glGetFramebufferAttachmentParameteriv, void, (GLenum p1, GLenum p2, GLenum p3, GLint* p4), (p1, p2, p3, p4))\ | ||
| + USE_FUNCTION (glTransformFeedbackVaryings, void, (GLuint p1, GLsizei p2, const char **p3, GLenum p4), (p1, p2, p3, p4))\ | ||
| + USE_FUNCTION (glBeginTransformFeedback, void, (GLenum p1), (p1))\ | ||
| + USE_FUNCTION (glEndTransformFeedback, void, (), ())\ | ||
| + USE_FUNCTION (glBindBufferBase, void, (GLenum p1, GLuint p2, GLuint p3), (p1, p2, p3))\ | ||
| + USE_FUNCTION (glMapBufferRange, void*, (GLenum p1, GLintptr p2, GLsizeiptr p3, GLbitfield p4), (p1, p2, p3, p4))\ | ||
| + USE_FUNCTION (glUnmapBuffer, GLboolean, (GLenum p1), (p1)); | ||
|
|
||
| /** @internal This macro contains a list of GL extension functions that need to be dynamically loaded on Windows/Linux. | ||
| @see OpenGLExtensionFunctions |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp | ||
| index 206a64afc..aa6196934 100644 | ||
| --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp | ||
| +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp | ||
| @@ -67,11 +67,11 @@ namespace FUnknownPrivate { | ||
| //------------------------------------------------------------------------ | ||
| int32 PLUGIN_API atomicAdd (int32& var, int32 d) | ||
| { | ||
| -#if SMTG_OS_WINDOWS | ||
| +#if SMTG_OS_WINDOWS && !defined(__MINGW32__) | ||
| return InterlockedExchangeAdd (&var, d) + d; | ||
| #elif SMTG_OS_MACOS | ||
| return OSAtomicAdd32Barrier (d, (int32_t*)&var); | ||
| -#elif SMTG_OS_LINUX | ||
| +#elif SMTG_OS_LINUX || defined(__MINGW32__) | ||
| __gnu_cxx::__atomic_add (&var, d); | ||
| return var; | ||
| #else |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
|  | ||
|
|
||
| JUCE is an open-source cross-platform C++ application framework used for rapidly | ||
| developing high quality desktop and mobile applications, including VST, AU (and AUv3), | ||
| RTAS and AAX audio plug-ins. JUCE can be easily integrated with existing projects 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, CLion and Linux Makefiles as well as containing a source code editor and | ||
| live-coding engine which can be used for rapid prototyping. | ||
|
|
||
| ## 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 minumum 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 for plugin projects, and strongly | ||
| recommended for other project types. 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__: macOS 10.11 and Xcode 7.3.1 | ||
| - __Windows__: Windows 8.1 and Visual Studio 2015 64-bit | ||
| - __Linux__: GCC 4.8 (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 | ||
|
|
||
| For bug reports and features requests, please visit the [JUCE Forum](https://forum.juce.com/) - | ||
| the JUCE developers are active there and will read every post and respond accordingly. When | ||
| submitting a bug report, please ensure that it follows the | ||
| [issue template](/.github/ISSUE_TEMPLATE.txt). | ||
| We don't accept third party GitHub pull requests directly due to copyright restrictions | ||
| but if you would like to contribute any changes please contact us. | ||
|
|
||
| ## License | ||
|
|
||
| The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_blocks_basics, 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). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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 | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| /** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method. | ||
| */ | ||
| struct JUCE_API CurrentPositionInfo | ||
| { | ||
| /** The tempo in BPM */ | ||
| double bpm; | ||
|
|
||
| /** Time signature numerator, e.g. the 3 of a 3/4 time sig */ | ||
| int timeSigNumerator; | ||
| /** Time signature denominator, e.g. the 4 of a 3/4 time sig */ | ||
| int timeSigDenominator; | ||
|
|
||
| /** The current play position, in samples from the start of the timeline. */ | ||
| int64 timeInSamples; | ||
| /** The current play position, in seconds from the start of the timeline. */ | ||
| double timeInSeconds; | ||
|
|
||
| /** For timecode, the position of the start of the timeline, in seconds from 00:00:00:00. */ | ||
| double editOriginTime; | ||
|
|
||
| /** The current play position, in units of quarter-notes. */ | ||
| double ppqPosition; | ||
|
|
||
| /** 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; | ||
|
|
||
| /** The video frame rate, if applicable. */ | ||
| FrameRateType frameRate; | ||
|
|
||
| /** True if the transport is currently playing. */ | ||
| bool isPlaying; | ||
|
|
||
| /** True if the transport is currently recording. | ||
| (When isRecording is true, then isPlaying will also be true). | ||
| */ | ||
| bool isRecording; | ||
|
|
||
| /** 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; | ||
|
|
||
| /** 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; | ||
|
|
||
| /** True if the transport is currently looping. */ | ||
| bool isLooping; | ||
|
|
||
| //============================================================================== | ||
| bool operator== (const CurrentPositionInfo& other) const noexcept | ||
| { | ||
| return timeInSamples == other.timeInSamples | ||
| && ppqPosition == other.ppqPosition | ||
| && editOriginTime == other.editOriginTime | ||
| && ppqPositionOfLastBarStart == other.ppqPositionOfLastBarStart | ||
| && frameRate == other.frameRate | ||
| && isPlaying == other.isPlaying | ||
| && isRecording == other.isRecording | ||
| && bpm == other.bpm | ||
| && timeSigNumerator == other.timeSigNumerator | ||
| && timeSigDenominator == other.timeSigDenominator | ||
| && ppqLoopStart == other.ppqLoopStart | ||
| && ppqLoopEnd == other.ppqLoopEnd | ||
| && isLooping == other.isLooping; | ||
| } | ||
|
|
||
| bool operator!= (const CurrentPositionInfo& other) const noexcept | ||
| { | ||
| return ! operator== (other); | ||
| } | ||
|
|
||
| void resetToDefault() | ||
| { | ||
| zerostruct (*this); | ||
| timeSigNumerator = 4; | ||
| timeSigDenominator = 4; | ||
| bpm = 120; | ||
| } | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| /** 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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 | ||
| { | ||
|
|
||
| AudioProcessLoadMeasurer::AudioProcessLoadMeasurer() {} | ||
| AudioProcessLoadMeasurer::~AudioProcessLoadMeasurer() {} | ||
|
|
||
| void AudioProcessLoadMeasurer::reset() | ||
| { | ||
| reset (0, 0); | ||
| } | ||
|
|
||
| void AudioProcessLoadMeasurer::reset (double sampleRate, int blockSize) | ||
| { | ||
| cpuUsageMs = 0; | ||
| xruns = 0; | ||
|
|
||
| if (sampleRate > 0.0 && blockSize > 0) | ||
| { | ||
| msPerBlock = 1000.0 * blockSize / sampleRate; | ||
| timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0; | ||
| } | ||
| else | ||
| { | ||
| msPerBlock = 0; | ||
| timeToCpuScale = 0; | ||
| } | ||
| } | ||
|
|
||
| void AudioProcessLoadMeasurer::registerBlockRenderTime (double milliseconds) | ||
| { | ||
| const double filterAmount = 0.2; | ||
| cpuUsageMs += filterAmount * (milliseconds - cpuUsageMs); | ||
|
|
||
| if (milliseconds > msPerBlock) | ||
| ++xruns; | ||
| } | ||
|
|
||
| double AudioProcessLoadMeasurer::getLoadAsProportion() const { return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs); } | ||
| double AudioProcessLoadMeasurer::getLoadAsPercentage() const { return 100.0 * getLoadAsProportion(); } | ||
|
|
||
| int AudioProcessLoadMeasurer::getXRunCount() const { return xruns; } | ||
|
|
||
| AudioProcessLoadMeasurer::ScopedTimer::ScopedTimer (AudioProcessLoadMeasurer& p) | ||
| : owner (p), startTime (Time::getMillisecondCounterHiRes()) | ||
| { | ||
| } | ||
|
|
||
| AudioProcessLoadMeasurer::ScopedTimer::~ScopedTimer() | ||
| { | ||
| owner.registerBlockRenderTime (Time::getMillisecondCounterHiRes() - startTime); | ||
| } | ||
|
|
||
| } // namespace juce |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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 | ||
| { | ||
|
|
||
| //============================================================================== | ||
| /** | ||
| Maintains an ongoing measurement of the proportion of time which is being | ||
| spent inside an audio callback. | ||
| @tags{Audio} | ||
| */ | ||
| class JUCE_API AudioProcessLoadMeasurer | ||
| { | ||
| public: | ||
| /** */ | ||
| AudioProcessLoadMeasurer(); | ||
|
|
||
| /** Destructor. */ | ||
| ~AudioProcessLoadMeasurer(); | ||
|
|
||
| //============================================================================== | ||
| /** Resets the state. */ | ||
| void reset(); | ||
|
|
||
| /** Resets the counter, in preparation for use with the given sample rate and block size. */ | ||
| void reset (double sampleRate, int blockSize); | ||
|
|
||
| /** Returns the current load as a proportion 0 to 1.0 */ | ||
| double getLoadAsProportion() const; | ||
|
|
||
| /** Returns the current load as a percentage 0 to 100.0 */ | ||
| double getLoadAsPercentage() const; | ||
|
|
||
| /** Returns the number of over- (or under-) runs recorded since the state was reset. */ | ||
| int getXRunCount() const; | ||
|
|
||
| //============================================================================== | ||
| /** This class measures the time between its construction and destruction and | ||
| adds it to an AudioProcessLoadMeasurer. | ||
| e.g. | ||
| @code | ||
| { | ||
| AudioProcessLoadMeasurer::ScopedTimer timer (myProcessLoadMeasurer); | ||
| myCallback->doTheCallback(); | ||
| } | ||
| @endcode | ||
| @tags{Audio} | ||
| */ | ||
| struct JUCE_API ScopedTimer | ||
| { | ||
| ScopedTimer (AudioProcessLoadMeasurer&); | ||
| ~ScopedTimer(); | ||
|
|
||
| private: | ||
| AudioProcessLoadMeasurer& owner; | ||
| double startTime; | ||
|
|
||
| JUCE_DECLARE_NON_COPYABLE (ScopedTimer) | ||
| }; | ||
|
|
||
| /** 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 registerBlockRenderTime (double millisecondsTaken); | ||
|
|
||
| private: | ||
| double cpuUsageMs = 0, timeToCpuScale = 0, msPerBlock = 0; | ||
| int xruns = 0; | ||
| }; | ||
|
|
||
|
|
||
| } // namespace juce |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,257 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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 | ||
| { | ||
|
|
||
| #ifndef JUCE_SNAP_TO_ZERO | ||
| #if JUCE_INTEL | ||
| #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0; | ||
| #else | ||
| #define JUCE_SNAP_TO_ZERO(n) ignoreUnused (n) | ||
| #endif | ||
| #endif | ||
| class ScopedNoDenormals; | ||
|
|
||
| //============================================================================== | ||
| /** | ||
| A collection of simple vector operations on arrays of floats, accelerated with | ||
| SIMD instructions where possible. | ||
| @tags{Audio} | ||
| */ | ||
| class JUCE_API FloatVectorOperations | ||
| { | ||
| public: | ||
| //============================================================================== | ||
| /** Clears a vector of floats. */ | ||
| static void JUCE_CALLTYPE clear (float* dest, int numValues) noexcept; | ||
|
|
||
| /** Clears a vector of doubles. */ | ||
| static void JUCE_CALLTYPE clear (double* dest, int numValues) noexcept; | ||
|
|
||
| /** Copies a repeated value into a vector of floats. */ | ||
| static void JUCE_CALLTYPE fill (float* dest, float valueToFill, int numValues) noexcept; | ||
|
|
||
| /** Copies a repeated value into a vector of doubles. */ | ||
| static void JUCE_CALLTYPE fill (double* dest, double valueToFill, int numValues) noexcept; | ||
|
|
||
| /** Copies a vector of floats. */ | ||
| static void JUCE_CALLTYPE copy (float* dest, const float* src, int numValues) noexcept; | ||
|
|
||
| /** Copies a vector of doubles. */ | ||
| static void JUCE_CALLTYPE copy (double* dest, const double* src, int numValues) noexcept; | ||
|
|
||
| /** Copies a vector of floats, multiplying each value by a given multiplier */ | ||
| static void JUCE_CALLTYPE copyWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; | ||
|
|
||
| /** Copies a vector of doubles, multiplying each value by a given multiplier */ | ||
| static void JUCE_CALLTYPE copyWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; | ||
|
|
||
| /** Adds a fixed value to the destination values. */ | ||
| static void JUCE_CALLTYPE add (float* dest, float amountToAdd, int numValues) noexcept; | ||
|
|
||
| /** Adds a fixed value to the destination values. */ | ||
| static void JUCE_CALLTYPE add (double* dest, double amountToAdd, int numValues) noexcept; | ||
|
|
||
| /** Adds a fixed value to each source value and stores it in the destination array. */ | ||
| static void JUCE_CALLTYPE add (float* dest, const float* src, float amount, int numValues) noexcept; | ||
|
|
||
| /** Adds a fixed value to each source value and stores it in the destination array. */ | ||
| static void JUCE_CALLTYPE add (double* dest, const double* src, double amount, int numValues) noexcept; | ||
|
|
||
| /** Adds the source values to the destination values. */ | ||
| static void JUCE_CALLTYPE add (float* dest, const float* src, int numValues) noexcept; | ||
|
|
||
| /** Adds the source values to the destination values. */ | ||
| static void JUCE_CALLTYPE add (double* dest, const double* src, int numValues) noexcept; | ||
|
|
||
| /** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */ | ||
| static void JUCE_CALLTYPE add (float* dest, const float* src1, const float* src2, int num) noexcept; | ||
|
|
||
| /** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */ | ||
| static void JUCE_CALLTYPE add (double* dest, const double* src1, const double* src2, int num) noexcept; | ||
|
|
||
| /** Subtracts the source values from the destination values. */ | ||
| static void JUCE_CALLTYPE subtract (float* dest, const float* src, int numValues) noexcept; | ||
|
|
||
| /** Subtracts the source values from the destination values. */ | ||
| static void JUCE_CALLTYPE subtract (double* dest, const double* src, int numValues) noexcept; | ||
|
|
||
| /** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */ | ||
| static void JUCE_CALLTYPE subtract (float* dest, const float* src1, const float* src2, int num) noexcept; | ||
|
|
||
| /** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */ | ||
| static void JUCE_CALLTYPE subtract (double* dest, const double* src1, const double* src2, int num) noexcept; | ||
|
|
||
| /** Multiplies each source value by the given multiplier, then adds it to the destination value. */ | ||
| static void JUCE_CALLTYPE addWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each source value by the given multiplier, then adds it to the destination value. */ | ||
| static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */ | ||
| static void JUCE_CALLTYPE addWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept; | ||
|
|
||
| /** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */ | ||
| static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept; | ||
|
|
||
| /** Multiplies each source value by the given multiplier, then subtracts it to the destination value. */ | ||
| static void JUCE_CALLTYPE subtractWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each source value by the given multiplier, then subtracts it to the destination value. */ | ||
| static void JUCE_CALLTYPE subtractWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each source1 value by the corresponding source2 value, then subtracts it to the destination value. */ | ||
| static void JUCE_CALLTYPE subtractWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept; | ||
|
|
||
| /** Multiplies each source1 value by the corresponding source2 value, then subtracts it to the destination value. */ | ||
| static void JUCE_CALLTYPE subtractWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept; | ||
|
|
||
| /** Multiplies the destination values by the source values. */ | ||
| static void JUCE_CALLTYPE multiply (float* dest, const float* src, int numValues) noexcept; | ||
|
|
||
| /** Multiplies the destination values by the source values. */ | ||
| static void JUCE_CALLTYPE multiply (double* dest, const double* src, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */ | ||
| static void JUCE_CALLTYPE multiply (float* dest, const float* src1, const float* src2, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */ | ||
| static void JUCE_CALLTYPE multiply (double* dest, const double* src1, const double* src2, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each of the destination values by a fixed multiplier. */ | ||
| static void JUCE_CALLTYPE multiply (float* dest, float multiplier, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each of the destination values by a fixed multiplier. */ | ||
| static void JUCE_CALLTYPE multiply (double* dest, double multiplier, int numValues) noexcept; | ||
|
|
||
| /** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */ | ||
| static void JUCE_CALLTYPE multiply (float* dest, const float* src, float multiplier, int num) noexcept; | ||
|
|
||
| /** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */ | ||
| static void JUCE_CALLTYPE multiply (double* dest, const double* src, double multiplier, int num) noexcept; | ||
|
|
||
| /** Copies a source vector to a destination, negating each value. */ | ||
| static void JUCE_CALLTYPE negate (float* dest, const float* src, int numValues) noexcept; | ||
|
|
||
| /** Copies a source vector to a destination, negating each value. */ | ||
| static void JUCE_CALLTYPE negate (double* dest, const double* src, int numValues) noexcept; | ||
|
|
||
| /** Copies a source vector to a destination, taking the absolute of each value. */ | ||
| static void JUCE_CALLTYPE abs (float* dest, const float* src, int numValues) noexcept; | ||
|
|
||
| /** Copies a source vector to a destination, taking the absolute of each value. */ | ||
| static void JUCE_CALLTYPE abs (double* dest, const double* src, int numValues) noexcept; | ||
|
|
||
| /** Converts a stream of integers to floats, multiplying each one by the given multiplier. */ | ||
| static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int numValues) noexcept; | ||
|
|
||
| /** Each element of dest will be the minimum of the corresponding element of the source array and the given comp value. */ | ||
| static void JUCE_CALLTYPE min (float* dest, const float* src, float comp, int num) noexcept; | ||
|
|
||
| /** Each element of dest will be the minimum of the corresponding element of the source array and the given comp value. */ | ||
| static void JUCE_CALLTYPE min (double* dest, const double* src, double comp, int num) noexcept; | ||
|
|
||
| /** Each element of dest will be the minimum of the corresponding source1 and source2 values. */ | ||
| static void JUCE_CALLTYPE min (float* dest, const float* src1, const float* src2, int num) noexcept; | ||
|
|
||
| /** Each element of dest will be the minimum of the corresponding source1 and source2 values. */ | ||
| static void JUCE_CALLTYPE min (double* dest, const double* src1, const double* src2, int num) noexcept; | ||
|
|
||
| /** Each element of dest will be the maximum of the corresponding element of the source array and the given comp value. */ | ||
| static void JUCE_CALLTYPE max (float* dest, const float* src, float comp, int num) noexcept; | ||
|
|
||
| /** Each element of dest will be the maximum of the corresponding element of the source array and the given comp value. */ | ||
| static void JUCE_CALLTYPE max (double* dest, const double* src, double comp, int num) noexcept; | ||
|
|
||
| /** Each element of dest will be the maximum of the corresponding source1 and source2 values. */ | ||
| static void JUCE_CALLTYPE max (float* dest, const float* src1, const float* src2, int num) noexcept; | ||
|
|
||
| /** Each element of dest will be the maximum of the corresponding source1 and source2 values. */ | ||
| static void JUCE_CALLTYPE max (double* dest, const double* src1, const double* src2, int num) noexcept; | ||
|
|
||
| /** Each element of dest is calculated by hard clipping the corresponding src element so that it is in the range specified by the arguments low and high. */ | ||
| static void JUCE_CALLTYPE clip (float* dest, const float* src, float low, float high, int num) noexcept; | ||
|
|
||
| /** Each element of dest is calculated by hard clipping the corresponding src element so that it is in the range specified by the arguments low and high. */ | ||
| static void JUCE_CALLTYPE clip (double* dest, const double* src, double low, double high, int num) noexcept; | ||
|
|
||
| /** Finds the minimum and maximum values in the given array. */ | ||
| static Range<float> JUCE_CALLTYPE findMinAndMax (const float* src, int numValues) noexcept; | ||
|
|
||
| /** Finds the minimum and maximum values in the given array. */ | ||
| static Range<double> JUCE_CALLTYPE findMinAndMax (const double* src, int numValues) noexcept; | ||
|
|
||
| /** Finds the minimum value in the given array. */ | ||
| static float JUCE_CALLTYPE findMinimum (const float* src, int numValues) noexcept; | ||
|
|
||
| /** Finds the minimum value in the given array. */ | ||
| static double JUCE_CALLTYPE findMinimum (const double* src, int numValues) noexcept; | ||
|
|
||
| /** Finds the maximum value in the given array. */ | ||
| static float JUCE_CALLTYPE findMaximum (const float* src, int numValues) noexcept; | ||
|
|
||
| /** Finds the maximum value in the given array. */ | ||
| static double JUCE_CALLTYPE findMaximum (const double* src, int numValues) noexcept; | ||
|
|
||
| /** This method enables or disables the SSE/NEON flush-to-zero mode. */ | ||
| static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept; | ||
|
|
||
| /** On Intel CPUs, this method enables the SSE flush-to-zero and denormalised-are-zero modes. | ||
| This effectively sets the DAZ and FZ bits of the MXCSR register. On arm CPUs this will | ||
| enable flush to zero mode. | ||
| It's a convenient thing to call before audio processing code where you really want to | ||
| avoid denormalisation performance hits. | ||
| */ | ||
| static void JUCE_CALLTYPE disableDenormalisedNumberSupport (bool shouldDisable = true) noexcept; | ||
|
|
||
| /** This method returns true if denormals are currently disabled. */ | ||
| static bool JUCE_CALLTYPE areDenormalsDisabled() noexcept; | ||
|
|
||
| private: | ||
| friend ScopedNoDenormals; | ||
|
|
||
| static intptr_t JUCE_CALLTYPE getFpStatusRegister() noexcept; | ||
| static void JUCE_CALLTYPE setFpStatusRegister (intptr_t) noexcept; | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| /** | ||
| Helper class providing an RAII-based mechanism for temporarily disabling | ||
| denormals on your CPU. | ||
| @tags{Audio} | ||
| */ | ||
| class ScopedNoDenormals | ||
| { | ||
| public: | ||
| ScopedNoDenormals() noexcept; | ||
| ~ScopedNoDenormals() noexcept; | ||
|
|
||
| private: | ||
| #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) | ||
| intptr_t fpsr; | ||
| #endif | ||
| }; | ||
|
|
||
| } // namespace juce |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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. | ||
| ============================================================================== | ||
| */ | ||
|
|
||
| #ifdef JUCE_AUDIO_BASICS_H_INCLUDED | ||
| /* When you add this cpp file to your project, you mustn't include it in a file where you've | ||
| already included any other headers - just put it inside a file on its own, possibly with your config | ||
| flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix | ||
| header files that the compiler may be using. | ||
| */ | ||
| #error "Incorrect use of JUCE cpp file" | ||
| #endif | ||
|
|
||
| #include "juce_audio_basics.h" | ||
|
|
||
| #if JUCE_MINGW && ! defined (alloca) | ||
| #define alloca __builtin_alloca | ||
| #endif | ||
|
|
||
| #if JUCE_USE_SSE_INTRINSICS | ||
| #include <emmintrin.h> | ||
| #endif | ||
|
|
||
| #ifndef JUCE_USE_VDSP_FRAMEWORK | ||
| #define JUCE_USE_VDSP_FRAMEWORK 1 | ||
| #endif | ||
|
|
||
| #if (JUCE_MAC || JUCE_IOS) && JUCE_USE_VDSP_FRAMEWORK | ||
| #include <Accelerate/Accelerate.h> | ||
| #else | ||
| #undef JUCE_USE_VDSP_FRAMEWORK | ||
| #endif | ||
|
|
||
| #if JUCE_USE_ARM_NEON | ||
| #include <arm_neon.h> | ||
| #endif | ||
|
|
||
| #include "buffers/juce_AudioDataConverters.cpp" | ||
| #include "buffers/juce_FloatVectorOperations.cpp" | ||
| #include "buffers/juce_AudioChannelSet.cpp" | ||
| #include "buffers/juce_AudioProcessLoadMeasurer.cpp" | ||
| #include "utilities/juce_IIRFilter.cpp" | ||
| #include "utilities/juce_LagrangeInterpolator.cpp" | ||
| #include "utilities/juce_WindowedSincInterpolator.cpp" | ||
| #include "utilities/juce_Interpolators.cpp" | ||
| #include "utilities/juce_SmoothedValue.cpp" | ||
| #include "midi/juce_MidiBuffer.cpp" | ||
| #include "midi/juce_MidiFile.cpp" | ||
| #include "midi/juce_MidiKeyboardState.cpp" | ||
| #include "midi/juce_MidiMessage.cpp" | ||
| #include "midi/juce_MidiMessageSequence.cpp" | ||
| #include "midi/juce_MidiRPN.cpp" | ||
| #include "mpe/juce_MPEValue.cpp" | ||
| #include "mpe/juce_MPENote.cpp" | ||
| #include "mpe/juce_MPEZoneLayout.cpp" | ||
| #include "mpe/juce_MPEInstrument.cpp" | ||
| #include "mpe/juce_MPEMessages.cpp" | ||
| #include "mpe/juce_MPESynthesiserBase.cpp" | ||
| #include "mpe/juce_MPESynthesiserVoice.cpp" | ||
| #include "mpe/juce_MPESynthesiser.cpp" | ||
| #include "mpe/juce_MPEUtils.cpp" | ||
| #include "sources/juce_BufferingAudioSource.cpp" | ||
| #include "sources/juce_ChannelRemappingAudioSource.cpp" | ||
| #include "sources/juce_IIRFilterAudioSource.cpp" | ||
| #include "sources/juce_MemoryAudioSource.cpp" | ||
| #include "sources/juce_MixerAudioSource.cpp" | ||
| #include "sources/juce_ResamplingAudioSource.cpp" | ||
| #include "sources/juce_ReverbAudioSource.cpp" | ||
| #include "sources/juce_ToneGeneratorAudioSource.cpp" | ||
| #include "synthesisers/juce_Synthesiser.cpp" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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. | ||
| ============================================================================== | ||
| */ | ||
|
|
||
|
|
||
| /******************************************************************************* | ||
| The block below describes the properties of this module, and is read by | ||
| the Projucer to automatically generate project code that uses it. | ||
| For details about the syntax and how to create or use a module, see the | ||
| JUCE Module Format.md file. | ||
| BEGIN_JUCE_MODULE_DECLARATION | ||
| ID: juce_audio_basics | ||
| vendor: juce | ||
| version: 6.0.8 | ||
| name: JUCE audio and MIDI data classes | ||
| description: Classes for audio buffer manipulation, midi message handling, synthesis, etc. | ||
| website: http://www.juce.com/juce | ||
| license: ISC | ||
| dependencies: juce_core | ||
| OSXFrameworks: Accelerate | ||
| iOSFrameworks: Accelerate | ||
| END_JUCE_MODULE_DECLARATION | ||
| *******************************************************************************/ | ||
|
|
||
|
|
||
| #pragma once | ||
| #define JUCE_AUDIO_BASICS_H_INCLUDED | ||
|
|
||
| #include <juce_core/juce_core.h> | ||
|
|
||
| //============================================================================== | ||
| #undef Complex // apparently some C libraries actually define these symbols (!) | ||
| #undef Factor | ||
|
|
||
| //============================================================================== | ||
| #if JUCE_MINGW && ! defined (__SSE2__) | ||
| #define JUCE_USE_SSE_INTRINSICS 0 | ||
| #endif | ||
|
|
||
| #ifndef JUCE_USE_SSE_INTRINSICS | ||
| #define JUCE_USE_SSE_INTRINSICS 1 | ||
| #endif | ||
|
|
||
| #if ! JUCE_INTEL | ||
| #undef JUCE_USE_SSE_INTRINSICS | ||
| #endif | ||
|
|
||
| #if __ARM_NEON__ && ! (JUCE_USE_VDSP_FRAMEWORK || defined (JUCE_USE_ARM_NEON)) | ||
| #define JUCE_USE_ARM_NEON 1 | ||
| #endif | ||
|
|
||
| #if TARGET_IPHONE_SIMULATOR | ||
| #ifdef JUCE_USE_ARM_NEON | ||
| #undef JUCE_USE_ARM_NEON | ||
| #endif | ||
| #define JUCE_USE_ARM_NEON 0 | ||
| #endif | ||
|
|
||
| //============================================================================== | ||
| #include "buffers/juce_AudioDataConverters.h" | ||
| #include "buffers/juce_FloatVectorOperations.h" | ||
| #include "buffers/juce_AudioSampleBuffer.h" | ||
| #include "buffers/juce_AudioChannelSet.h" | ||
| #include "buffers/juce_AudioProcessLoadMeasurer.h" | ||
| #include "utilities/juce_Decibels.h" | ||
| #include "utilities/juce_IIRFilter.h" | ||
| #include "utilities/juce_GenericInterpolator.h" | ||
| #include "utilities/juce_Interpolators.h" | ||
| #include "utilities/juce_SmoothedValue.h" | ||
| #include "utilities/juce_Reverb.h" | ||
| #include "utilities/juce_ADSR.h" | ||
| #include "midi/juce_MidiMessage.h" | ||
| #include "midi/juce_MidiBuffer.h" | ||
| #include "midi/juce_MidiMessageSequence.h" | ||
| #include "midi/juce_MidiFile.h" | ||
| #include "midi/juce_MidiKeyboardState.h" | ||
| #include "midi/juce_MidiRPN.h" | ||
| #include "mpe/juce_MPEValue.h" | ||
| #include "mpe/juce_MPENote.h" | ||
| #include "mpe/juce_MPEZoneLayout.h" | ||
| #include "mpe/juce_MPEInstrument.h" | ||
| #include "mpe/juce_MPEMessages.h" | ||
| #include "mpe/juce_MPESynthesiserBase.h" | ||
| #include "mpe/juce_MPESynthesiserVoice.h" | ||
| #include "mpe/juce_MPESynthesiser.h" | ||
| #include "mpe/juce_MPEUtils.h" | ||
| #include "sources/juce_AudioSource.h" | ||
| #include "sources/juce_PositionableAudioSource.h" | ||
| #include "sources/juce_BufferingAudioSource.h" | ||
| #include "sources/juce_ChannelRemappingAudioSource.h" | ||
| #include "sources/juce_IIRFilterAudioSource.h" | ||
| #include "sources/juce_MemoryAudioSource.h" | ||
| #include "sources/juce_MixerAudioSource.h" | ||
| #include "sources/juce_ResamplingAudioSource.h" | ||
| #include "sources/juce_ReverbAudioSource.h" | ||
| #include "sources/juce_ToneGeneratorAudioSource.h" | ||
| #include "synthesisers/juce_Synthesiser.h" | ||
| #include "audio_play_head/juce_AudioPlayHead.h" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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. | ||
| ============================================================================== | ||
| */ | ||
|
|
||
| #include "juce_audio_basics.cpp" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,308 @@ | ||
| /* | ||
| ============================================================================== | ||
| 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 | ||
| { | ||
|
|
||
| namespace MidiBufferHelpers | ||
| { | ||
| inline int getEventTime (const void* d) noexcept | ||
| { | ||
| return readUnaligned<int32> (d); | ||
| } | ||
|
|
||
| inline uint16 getEventDataSize (const void* d) noexcept | ||
| { | ||
| return readUnaligned<uint16> (static_cast<const char*> (d) + sizeof (int32)); | ||
| } | ||
|
|
||
| inline uint16 getEventTotalSize (const void* d) noexcept | ||
| { | ||
| return (uint16) (getEventDataSize (d) + sizeof (int32) + sizeof (uint16)); | ||
| } | ||
|
|
||
| static int findActualEventLength (const uint8* data, int maxBytes) noexcept | ||
| { | ||
| auto byte = (unsigned int) *data; | ||
|
|
||
| if (byte == 0xf0 || byte == 0xf7) | ||
| { | ||
| int i = 1; | ||
|
|
||
| while (i < maxBytes) | ||
| if (data[i++] == 0xf7) | ||
| break; | ||
|
|
||
| return i; | ||
| } | ||
|
|
||
| if (byte == 0xff) | ||
| { | ||
| if (maxBytes == 1) | ||
| return 1; | ||
|
|
||
| const auto var = MidiMessage::readVariableLengthValue (data + 1, maxBytes - 1); | ||
| return jmin (maxBytes, var.value + 2 + var.bytesUsed); | ||
| } | ||
|
|
||
| if (byte >= 0x80) | ||
| return jmin (maxBytes, MidiMessage::getMessageLengthFromFirstByte ((uint8) byte)); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static uint8* findEventAfter (uint8* d, uint8* endData, int samplePosition) noexcept | ||
| { | ||
| while (d < endData && getEventTime (d) <= samplePosition) | ||
| d += getEventTotalSize (d); | ||
|
|
||
| return d; | ||
| } | ||
| } | ||
|
|
||
| //============================================================================== | ||
| MidiBufferIterator& MidiBufferIterator::operator++() noexcept | ||
| { | ||
| data += sizeof (int32) + sizeof (uint16) + size_t (MidiBufferHelpers::getEventDataSize (data)); | ||
| return *this; | ||
| } | ||
|
|
||
| MidiBufferIterator MidiBufferIterator::operator++ (int) noexcept | ||
| { | ||
| auto copy = *this; | ||
| ++(*this); | ||
| return copy; | ||
| } | ||
|
|
||
| MidiBufferIterator::reference MidiBufferIterator::operator*() const noexcept | ||
| { | ||
| return { data + sizeof (int32) + sizeof (uint16), | ||
| MidiBufferHelpers::getEventDataSize (data), | ||
| MidiBufferHelpers::getEventTime (data) }; | ||
| } | ||
|
|
||
| //============================================================================== | ||
| MidiBuffer::MidiBuffer (const MidiMessage& message) noexcept | ||
| { | ||
| addEvent (message, 0); | ||
| } | ||
|
|
||
| void MidiBuffer::swapWith (MidiBuffer& other) noexcept { data.swapWith (other.data); } | ||
| void MidiBuffer::clear() noexcept { data.clearQuick(); } | ||
| void MidiBuffer::ensureSize (size_t minimumNumBytes) { data.ensureStorageAllocated ((int) minimumNumBytes); } | ||
| bool MidiBuffer::isEmpty() const noexcept { return data.size() == 0; } | ||
|
|
||
| void MidiBuffer::clear (int startSample, int numSamples) | ||
| { | ||
| auto start = MidiBufferHelpers::findEventAfter (data.begin(), data.end(), startSample - 1); | ||
| auto end = MidiBufferHelpers::findEventAfter (start, data.end(), startSample + numSamples - 1); | ||
|
|
||
| data.removeRange ((int) (start - data.begin()), (int) (end - start)); | ||
| } | ||
|
|
||
| void MidiBuffer::addEvent (const MidiMessage& m, int sampleNumber) | ||
| { | ||
| addEvent (m.getRawData(), m.getRawDataSize(), sampleNumber); | ||
| } | ||
|
|
||
| void MidiBuffer::addEvent (const void* newData, int maxBytes, int sampleNumber) | ||
| { | ||
| auto numBytes = MidiBufferHelpers::findActualEventLength (static_cast<const uint8*> (newData), maxBytes); | ||
|
|
||
| if (numBytes > 0) | ||
| { | ||
| auto newItemSize = (size_t) numBytes + sizeof (int32) + sizeof (uint16); | ||
| auto offset = (int) (MidiBufferHelpers::findEventAfter (data.begin(), data.end(), sampleNumber) - data.begin()); | ||
|
|
||
| data.insertMultiple (offset, 0, (int) newItemSize); | ||
|
|
||
| auto* d = data.begin() + offset; | ||
| writeUnaligned<int32> (d, sampleNumber); | ||
| d += sizeof (int32); | ||
| writeUnaligned<uint16> (d, static_cast<uint16> (numBytes)); | ||
| d += sizeof (uint16); | ||
| memcpy (d, newData, (size_t) numBytes); | ||
| } | ||
| } | ||
|
|
||
| void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, | ||
| int startSample, int numSamples, int sampleDeltaToAdd) | ||
| { | ||
| for (auto i = otherBuffer.findNextSamplePosition (startSample); i != otherBuffer.cend(); ++i) | ||
| { | ||
| const auto metadata = *i; | ||
|
|
||
| if (metadata.samplePosition >= startSample + numSamples && numSamples >= 0) | ||
| break; | ||
|
|
||
| addEvent (metadata.data, metadata.numBytes, metadata.samplePosition + sampleDeltaToAdd); | ||
| } | ||
| } | ||
|
|
||
| int MidiBuffer::getNumEvents() const noexcept | ||
| { | ||
| int n = 0; | ||
| auto end = data.end(); | ||
|
|
||
| for (auto d = data.begin(); d < end; ++n) | ||
| d += MidiBufferHelpers::getEventTotalSize (d); | ||
|
|
||
| return n; | ||
| } | ||
|
|
||
| int MidiBuffer::getFirstEventTime() const noexcept | ||
| { | ||
| return data.size() > 0 ? MidiBufferHelpers::getEventTime (data.begin()) : 0; | ||
| } | ||
|
|
||
| int MidiBuffer::getLastEventTime() const noexcept | ||
| { | ||
| if (data.size() == 0) | ||
| return 0; | ||
|
|
||
| auto endData = data.end(); | ||
|
|
||
| for (auto d = data.begin();;) | ||
| { | ||
| auto nextOne = d + MidiBufferHelpers::getEventTotalSize (d); | ||
|
|
||
| if (nextOne >= endData) | ||
| return MidiBufferHelpers::getEventTime (d); | ||
|
|
||
| d = nextOne; | ||
| } | ||
| } | ||
|
|
||
| MidiBufferIterator MidiBuffer::findNextSamplePosition (int samplePosition) const noexcept | ||
| { | ||
| return std::find_if (cbegin(), cend(), [&] (const MidiMessageMetadata& metadata) noexcept | ||
| { | ||
| return metadata.samplePosition >= samplePosition; | ||
| }); | ||
| } | ||
|
|
||
| //============================================================================== | ||
| MidiBuffer::Iterator::Iterator (const MidiBuffer& b) noexcept | ||
| : buffer (b), iterator (b.data.begin()) | ||
| { | ||
| } | ||
|
|
||
| MidiBuffer::Iterator::~Iterator() noexcept {} | ||
|
|
||
| void MidiBuffer::Iterator::setNextSamplePosition (int samplePosition) noexcept | ||
| { | ||
| iterator = buffer.findNextSamplePosition (samplePosition); | ||
| } | ||
|
|
||
| bool MidiBuffer::Iterator::getNextEvent (const uint8*& midiData, int& numBytes, int& samplePosition) noexcept | ||
| { | ||
| if (iterator == buffer.cend()) | ||
| return false; | ||
|
|
||
| const auto metadata = *iterator++; | ||
| midiData = metadata.data; | ||
| numBytes = metadata.numBytes; | ||
| samplePosition = metadata.samplePosition; | ||
| return true; | ||
| } | ||
|
|
||
| bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePosition) noexcept | ||
| { | ||
| if (iterator == buffer.cend()) | ||
| return false; | ||
|
|
||
| const auto metadata = *iterator++; | ||
| result = metadata.getMessage(); | ||
| samplePosition = metadata.samplePosition; | ||
| return true; | ||
| } | ||
|
|
||
| //============================================================================== | ||
| //============================================================================== | ||
| #if JUCE_UNIT_TESTS | ||
|
|
||
| struct MidiBufferTest : public UnitTest | ||
| { | ||
| MidiBufferTest() | ||
| : UnitTest ("MidiBuffer", UnitTestCategories::midi) | ||
| {} | ||
|
|
||
| void runTest() override | ||
| { | ||
| beginTest ("Clear messages"); | ||
| { | ||
| const auto message = MidiMessage::noteOn (1, 64, 0.5f); | ||
|
|
||
| const auto testBuffer = [&] | ||
| { | ||
| MidiBuffer buffer; | ||
| buffer.addEvent (message, 0); | ||
| buffer.addEvent (message, 10); | ||
| buffer.addEvent (message, 20); | ||
| buffer.addEvent (message, 30); | ||
| return buffer; | ||
| }(); | ||
|
|
||
| { | ||
| auto buffer = testBuffer; | ||
| buffer.clear (10, 0); | ||
| expectEquals (buffer.getNumEvents(), 4); | ||
| } | ||
|
|
||
| { | ||
| auto buffer = testBuffer; | ||
| buffer.clear (10, 1); | ||
| expectEquals (buffer.getNumEvents(), 3); | ||
| } | ||
|
|
||
| { | ||
| auto buffer = testBuffer; | ||
| buffer.clear (10, 10); | ||
| expectEquals (buffer.getNumEvents(), 3); | ||
| } | ||
|
|
||
| { | ||
| auto buffer = testBuffer; | ||
| buffer.clear (10, 20); | ||
| expectEquals (buffer.getNumEvents(), 2); | ||
| } | ||
|
|
||
| { | ||
| auto buffer = testBuffer; | ||
| buffer.clear (10, 30); | ||
| expectEquals (buffer.getNumEvents(), 1); | ||
| } | ||
|
|
||
| { | ||
| auto buffer = testBuffer; | ||
| buffer.clear (10, 300); | ||
| expectEquals (buffer.getNumEvents(), 1); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| static MidiBufferTest midiBufferTest; | ||
|
|
||
| #endif | ||
|
|
||
| } // namespace juce |