+++ /dev/null
-Please include:
-
- 1) detailed steps on how to reproduce the bug, preferably with already
- existing JUCE code such as the demo plugin or the demo code
- 2) the expected behaviour
- 3) the operating system
- 4) the architecture (32-bit or 64-bit)
- 5) a stack trace - if the bug causes a crash
- 6) the plugin format (VST2, VST3, AU, AAX, RTAS) - if applicable
- 7) which DAW you observed the bug in - if applicable
-
-Make sure you have pulled the latest commits from the `develop` branch of the
-JUCE repo and have re-compiled the Projucer before you submit your bug. Often
-we have already fixed the issue but it hasn't yet been released on the `master`
-branch. If it's a major bug, which must be hot-fixed immediately, then we will
-also accept bug reports for tagged release versions.
-
+++ /dev/null
-include:
- - project: 'juce-repos/JUCE-utils'
- file: '/CI/gitlab-ci.yml'
-
JUCE breaking changes
=====================
+Version 5.4.5
+=============
+
+Change
+------
+The JUCEApplicationBase::backButtonPressed() method now returns a bool to
+indicate whether the back event was handled or not.
+
+Possible Issues
+---------------
+Applications which override this method will fail to compile.
+
+Workaround
+----------
+You will need to update your code to return a bool indicating whether the back
+event was handled or not.
+
+Rationale
+---------
+The back button behaviour on Android was previously broken as it would not do
+anything. The new code will correctly call finish() on the Activity when the
+back button is pressed but this method now allows the user to override this to
+implement their own custom navigation behaviour by returning true to indicate
+that it has been handled.
+
+
+Change
+------
+The AudioBlock class has been refactored and some of the method names have
+changed. Additionally the `const` behaviour now mirrors that of `std::span`,
+with the `const`-ness of the contained data decoupled from the `const`-ness of
+the container.
+
+Possible Issues
+---------------
+Code using the old method names or violating `const`-correctness will fail to
+compile.
+
+Workaround
+----------
+You will need to update your code to use the new method names and select an
+appropriate `const`-ness for the AudioBlock and the data it references.
+
+Rationale
+---------
+The names of some of the methods in the AudioBlock class were ambiguous,
+particularly when chaining methods involving references to other blocks. The
+interaction between the `const`-ness of the AudioBlock and the `const`-ness of
+the referenced data was also ambiguous and has now been standardised to the
+same behaviour as other non-owning data views like `std::span`.
+
+
Version 5.4.4
=============
This file just lists the more notable headline features. For more detailed info\r
about minor changes and bugfixes, please see the git log!\r
\r
+Version 5.4.5\r
+ - Improved message queue performance on Linux\r
+ - Added missing lifecycle callbacks on Android Q\r
+ - Refactored the AudioBlock class\r
+ - Fixed APVTS parameter update recursion\r
+ - Updated Bela code to support latest release\r
+ - Fixed issues drawing italicised text on macOS\r
+ - Fixed broken back button behaviour on Android\r
+ - Added Bluetooth permissions settings needed for iOS 13.0+ to the Projucer\r
+ - Replaced select() calls with poll()\r
+ - Various bug-fixes, improvements and documentation updates\r
+\r
Version 5.4.4\r
- Improvements to floating point number printing\r
- Faster plug-in parameter indexing\r
- Added support for persisting attachements to MIDI devices\r
- Refactored Linux event loop handling\r
- Multiple C++ modernisation improvements to the API\r
- - Added support for macOS 10.55 and iOS 13\r
+ - Added support for macOS 10.15 and iOS 13\r
- Added support for Visual Studio 2019\r
- Removed support for Visual Studio 2013\r
\r
"subdirectories")
args = parser.parse_args()
- try:
+ try:
shutil.rmtree(args.dest_dir)
+ except OSError:
+ pass
except FileNotFoundError:
pass
\r
void process (const ProcessContextReplacing<float>& context)\r
{\r
- tempBuffer.copy (context.getInputBlock());\r
- tempBuffer.multiply (static_cast<float> (fileMix));\r
+ tempBuffer.copyFrom (context.getInputBlock());\r
+ tempBuffer.multiplyBy (static_cast<float> (fileMix));\r
\r
oscillators[currentOscillatorIdx].process (context);\r
- context.getOutputBlock().multiply (static_cast<float> (1.0 - fileMix));\r
+ context.getOutputBlock().multiplyBy (static_cast<float> (1.0 - fileMix));\r
\r
context.getOutputBlock().add (tempBuffer);\r
\r
add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")
set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression")
-add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/roli/juce/JuceActivity\"" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.4.4" "-DJUCE_APP_VERSION_HEX=0x50404")
+add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/roli/juce/JuceActivity\"" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.4.5" "-DJUCE_APP_VERSION_HEX=0x50405")
include_directories( AFTER
"../../../JuceLibraryCode"
"../../../../../modules/juce_blocks_basics/protocol/Protocol Format.txt"
"../../../../../modules/juce_blocks_basics/topology/internal/juce_BandwidthStatsLogger.cpp"
"../../../../../modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp"
+ "../../../../../modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp"
"../../../../../modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp"
"../../../../../modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp"
"../../../../../modules/juce_blocks_basics/topology/internal/juce_Detector.cpp"
"../../../../../modules/juce_data_structures/juce_data_structures.mm"
"../../../../../modules/juce_data_structures/juce_data_structures.h"
"../../../../../modules/juce_dsp/containers/juce_AudioBlock.h"
+ "../../../../../modules/juce_dsp/containers/juce_AudioBlock_test.cpp"
"../../../../../modules/juce_dsp/containers/juce_SIMDRegister.h"
"../../../../../modules/juce_dsp/containers/juce_SIMDRegister_Impl.h"
"../../../../../modules/juce_dsp/containers/juce_SIMDRegister_test.cpp"
set_source_files_properties("../../../../../modules/juce_blocks_basics/protocol/Protocol Format.txt" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_blocks_basics/topology/internal/juce_BandwidthStatsLogger.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
+set_source_files_properties("../../../../../modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_blocks_basics/topology/internal/juce_Detector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.mm" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.h" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_AudioBlock.h" PROPERTIES HEADER_FILE_ONLY TRUE)
+set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_AudioBlock_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_SIMDRegister.h" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_SIMDRegister_Impl.h" PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_SIMDRegister_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="5.4.4"
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="5.4.5"
package="com.juce.demorunner">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
TARGET_ARCH := -march=native
endif
- JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCE_DEMO_RUNNER=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.4 -DJUCE_APP_VERSION_HEX=0x50404 $(shell pkg-config --cflags alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
+ JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCE_DEMO_RUNNER=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.5 -DJUCE_APP_VERSION_HEX=0x50405 $(shell pkg-config --cflags alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 -DJucePlugin_Build_Unity=0
JUCE_TARGET_APP := DemoRunner
TARGET_ARCH := -march=native
endif
- JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCE_DEMO_RUNNER=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.4 -DJUCE_APP_VERSION_HEX=0x50404 $(shell pkg-config --cflags alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
+ JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCE_DEMO_RUNNER=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.5 -DJUCE_APP_VERSION_HEX=0x50405 $(shell pkg-config --cflags alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 -DJucePlugin_Build_Unity=0
JUCE_TARGET_APP := DemoRunner
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = "../../../../modules/juce_audio_utils";
sourceTree = "SOURCE_ROOT";
};
+ 0CCFDC1D1C7B8A12BF4822F1 = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = DemoRunner.entitlements;
+ path = DemoRunner.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
0ECB4FCD24794CE516792552 = {
isa = PBXFileReference;
lastKnownFileType = folder;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
"JUCE_DEMO_RUNNER=1",
"JUCE_UNIT_TESTS=1",
"JUCER_XCODE_MAC_F6D2F4CF=1",
- "JUCE_APP_VERSION=5.4.4",
- "JUCE_APP_VERSION_HEX=0x50404",
+ "JUCE_APP_VERSION=5.4.5",
+ "JUCE_APP_VERSION_HEX=0x50405",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
"JUCE_DEMO_RUNNER=1",
"JUCE_UNIT_TESTS=1",
"JUCER_XCODE_MAC_F6D2F4CF=1",
- "JUCE_APP_VERSION=5.4.4",
- "JUCE_APP_VERSION_HEX=0x50404",
+ "JUCE_APP_VERSION=5.4.5",
+ "JUCE_APP_VERSION_HEX=0x50405",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c11;
<key>CFBundleSignature</key>\r
<string>????</string>\r
<key>CFBundleShortVersionString</key>\r
- <string>5.4.4</string>\r
+ <string>5.4.5</string>\r
<key>CFBundleVersion</key>\r
- <string>5.4.4</string>\r
+ <string>5.4.5</string>\r
<key>NSHumanReadableCopyright</key>\r
<string>Copyright (c) 2018 - ROLI Ltd.</string>\r
<key>NSHighResolutionCapable</key>\r
<Optimization>Disabled</Optimization>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile>\r
<Optimization>Full</Optimization>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm">\r
<Filter>JUCE Modules\juce_data_structures</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <Filter>JUCE Modules\juce_dsp\containers</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<Filter>JUCE Modules\juce_dsp\containers</Filter>\r
</ClCompile>\r
#include <windows.h>\r
\r
VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION 5,4,4,0\r
+FILEVERSION 5,4,5,0\r
BEGIN\r
BLOCK "StringFileInfo"\r
BEGIN\r
VALUE "CompanyName", "ROLI Ltd.\0"\r
VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0"\r
VALUE "FileDescription", "DemoRunner\0"\r
- VALUE "FileVersion", "5.4.4\0"\r
+ VALUE "FileVersion", "5.4.5\0"\r
VALUE "ProductName", "DemoRunner\0"\r
- VALUE "ProductVersion", "5.4.4\0"\r
+ VALUE "ProductVersion", "5.4.5\0"\r
END\r
END\r
\r
<Optimization>Disabled</Optimization>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile>\r
<Optimization>Full</Optimization>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm">\r
<Filter>JUCE Modules\juce_data_structures</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <Filter>JUCE Modules\juce_dsp\containers</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<Filter>JUCE Modules\juce_dsp\containers</Filter>\r
</ClCompile>\r
#include <windows.h>\r
\r
VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION 5,4,4,0\r
+FILEVERSION 5,4,5,0\r
BEGIN\r
BLOCK "StringFileInfo"\r
BEGIN\r
VALUE "CompanyName", "ROLI Ltd.\0"\r
VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0"\r
VALUE "FileDescription", "DemoRunner\0"\r
- VALUE "FileVersion", "5.4.4\0"\r
+ VALUE "FileVersion", "5.4.5\0"\r
VALUE "ProductName", "DemoRunner\0"\r
- VALUE "ProductVersion", "5.4.4\0"\r
+ VALUE "ProductVersion", "5.4.5\0"\r
END\r
END\r
\r
<Optimization>Disabled</Optimization>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile>\r
<Optimization>Full</Optimization>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm">\r
<Filter>JUCE Modules\juce_data_structures</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <Filter>JUCE Modules\juce_dsp\containers</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<Filter>JUCE Modules\juce_dsp\containers</Filter>\r
</ClCompile>\r
#include <windows.h>\r
\r
VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION 5,4,4,0\r
+FILEVERSION 5,4,5,0\r
BEGIN\r
BLOCK "StringFileInfo"\r
BEGIN\r
VALUE "CompanyName", "ROLI Ltd.\0"\r
VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0"\r
VALUE "FileDescription", "DemoRunner\0"\r
- VALUE "FileVersion", "5.4.4\0"\r
+ VALUE "FileVersion", "5.4.5\0"\r
VALUE "ProductName", "DemoRunner\0"\r
- VALUE "ProductVersion", "5.4.4\0"\r
+ VALUE "ProductVersion", "5.4.5\0"\r
END\r
END\r
\r
91A9A0FE9DF4F4E10009EEC7 = {
isa = PBXGroup;
children = (
- 0CCFDC1D1C7B8A12BF4822F1,
9683F931FA1B8B85FA8C4BD8,
5A0B2CEF393A25C6D4B1B76C,
61F3057D838D7DABB0FA3D34,
B18D059E5616FA729F764229 = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
"JUCE_DEMO_RUNNER=1",
"JUCE_UNIT_TESTS=1",
"JUCER_XCODE_IPHONE_5BC26AE3=1",
- "JUCE_APP_VERSION=5.4.4",
- "JUCE_APP_VERSION_HEX=0x50404",
+ "JUCE_APP_VERSION=5.4.5",
+ "JUCE_APP_VERSION_HEX=0x50405",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
69330F27DD2C71609336C7D2 = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
"JUCE_DEMO_RUNNER=1",
"JUCE_UNIT_TESTS=1",
"JUCER_XCODE_IPHONE_5BC26AE3=1",
- "JUCE_APP_VERSION=5.4.4",
- "JUCE_APP_VERSION_HEX=0x50404",
+ "JUCE_APP_VERSION=5.4.5",
+ "JUCE_APP_VERSION_HEX=0x50405",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
C01EC82F42B640CA1E54AD53 = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
07EA85D22270E8EA13CA0BBE = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
<string>This app requires audio input. If you do not have an audio interface connected it will use the built-in microphone.</string>\r
<key>NSCameraUsageDescription</key>\r
<string>This app requires access to the camera to function correctly.</string>\r
+ <key>NSBluetoothAlwaysUsageDescription</key>\r
+ <string>This app requires access to Bluetooth to function correctly.</string>\r
+ <key>NSBluetoothPeripheralUsageDescription</key>\r
+ <string>This app requires access to Bluetooth to function correctly.</string>\r
<key>LSRequiresIPhoneOS</key>\r
<true/>\r
<key>UIViewControllerBasedStatusBarAppearance</key>\r
<key>CFBundleSignature</key>\r
<string>????</string>\r
<key>CFBundleShortVersionString</key>\r
- <string>5.4.4</string>\r
+ <string>5.4.5</string>\r
<key>CFBundleVersion</key>\r
- <string>5.4.4</string>\r
+ <string>5.4.5</string>\r
<key>NSHumanReadableCopyright</key>\r
<string>Copyright (c) 2018 - ROLI Ltd.</string>\r
<key>NSHighResolutionCapable</key>\r
<?xml version="1.0" encoding="UTF-8"?>\r
\r
-<JUCERPROJECT name="DemoRunner" projectType="guiapp" jucerVersion="5.4.4" defines="JUCE_DEMO_RUNNER=1 JUCE_UNIT_TESTS=1"\r
- bundleIdentifier="com.juce.demorunner" version="5.4.4" companyName="ROLI Ltd."\r
+<JUCERPROJECT name="DemoRunner" projectType="guiapp" jucerVersion="5.4.5" defines="JUCE_DEMO_RUNNER=1 JUCE_UNIT_TESTS=1"\r
+ bundleIdentifier="com.juce.demorunner" version="5.4.5" companyName="ROLI Ltd."\r
companyCopyright="Copyright (c) 2018 - ROLI Ltd." companyWebsite="https://www.juce.com/"\r
companyEmail="info@juce.com" id="yj7xMM" reportAppUsage="1">\r
<MAINGROUP id="G8kbr7" name="DemoRunner">\r
</ANDROIDSTUDIO>\r
<XCODE_IPHONE targetFolder="Builds/iOS" UISupportsDocumentBrowser="1" microphonePermissionNeeded="1"\r
cameraPermissionNeeded="1" iCloudPermissions="1" UIFileSharingEnabled="1"\r
- customXcodeResourceFolders="../Assets" smallIcon="YyqWd2" bigIcon="YyqWd2">\r
+ customXcodeResourceFolders="../Assets" smallIcon="YyqWd2" bigIcon="YyqWd2"\r
+ iosBluetoothPermissionNeeded="1">\r
<CONFIGURATIONS>\r
<CONFIGURATION isDebug="1" name="Debug" recommendedWarnings="LLVM"/>\r
<CONFIGURATION isDebug="0" name="Release" recommendedWarnings="LLVM"/>\r
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_analytics 1\r
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1\r
#include <juce_video/juce_video.h>\r
\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
{\r
const char* const projectName = "DemoRunner";\r
const char* const companyName = "ROLI Ltd.";\r
- const char* const versionString = "5.4.4";\r
- const int versionNumber = 0x50404;\r
+ const char* const versionString = "5.4.5";\r
+ const int versionNumber = 0x50405;\r
}\r
#endif\r
mainWindow.reset (new MainAppWindow (getApplicationName()));\r
}\r
\r
- void backButtonPressed() override { mainWindow->getMainComponent().getSidePanel().showOrHide (false); }\r
+ bool backButtonPressed() override { mainWindow->getMainComponent().getSidePanel().showOrHide (false); return true; }\r
void shutdown() override { mainWindow = nullptr; }\r
\r
//==============================================================================\r
\r
bool DemoContentComponent::isShowingHomeScreen() const noexcept\r
{\r
- return isComponentIntroDemo (demoContent->getComponent());\r
+ return isComponentIntroDemo (demoContent->getComponent()) && getCurrentTabIndex() == 0;\r
}\r
\r
void DemoContentComponent::showHomeScreen()\r
process (dsp::ProcessContextReplacing<float> (firstChan));\r
\r
for (size_t chan = 1; chan < block.getNumChannels(); ++chan)\r
- block.getSingleChannelBlock (chan).copy (firstChan);\r
+ block.getSingleChannelBlock (chan).copyFrom (firstChan);\r
}\r
}\r
\r
<?xml version="1.0" encoding="UTF-8"?>\r
\r
<JUCERPROJECT id="AKfc5m" name="AudioPerformanceTest" projectType="guiapp"\r
- bundleIdentifier="com.juce.AudioPerformanceTest" jucerVersion="5.4.4"\r
+ bundleIdentifier="com.juce.AudioPerformanceTest" jucerVersion="5.4.5"\r
displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd."\r
companyCopyright="ROLI Ltd.">\r
<MAINGROUP id="b1eVTe" name="AudioPerformanceTest">\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = "../../JuceLibraryCode/include_juce_audio_utils.mm";
sourceTree = "SOURCE_ROOT";
};
+ C3BE13F50343166A30728D8A = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = AudioPerformanceTest.entitlements;
+ path = AudioPerformanceTest.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
C8EE61FDD1F06817A014B881 = {
isa = PBXFileReference;
lastKnownFileType = file;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c11;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = "../../JuceLibraryCode/include_juce_audio_utils.mm";
sourceTree = "SOURCE_ROOT";
};
+ C3BE13F50343166A30728D8A = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = AudioPerformanceTest.entitlements;
+ path = AudioPerformanceTest.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
C6030BFC7A19A5075AB0EC28 = {
isa = PBXFileReference;
lastKnownFileType = wrapper.framework;
19B7C16D592FB25D09022191 = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
B7A6988E30C0A68B01EDC53B = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
B907CDF95622107F20CD7617 = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
BF82CBDF63CC37CADC61A511 = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1\r
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1\r
#include <juce_gui_extra/juce_gui_extra.h>\r
\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
\r
<JUCERPROJECT id="NTe0XB0ij" name="AudioPluginHost" projectType="guiapp" version="1.0.0"\r
juceFolder="../../../juce" bundleIdentifier="com.roli.juce.pluginhost"\r
- jucerVersion="5.4.4" companyName="ROLI Ltd." displaySplashScreen="0"\r
+ jucerVersion="5.4.5" companyName="ROLI Ltd." displaySplashScreen="0"\r
reportAppUsage="0" companyCopyright="ROLI Ltd.">\r
<EXPORTFORMATS>\r
<XCODE_MAC targetFolder="Builds/MacOSX" rtasFolder="~/SDKs/PT_80_SDK" objCExtraSuffix="M73TRi"\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = System/Library/Frameworks/CoreAudioKit.framework;
sourceTree = SDKROOT;
};
+ EC252E34CF52A70B4A836BDC = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = AudioPluginHost.entitlements;
+ path = AudioPluginHost.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
F14CDB17EFE157DA3C3A5A91 = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c11;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = System/Library/Frameworks/CoreAudioKit.framework;
sourceTree = SDKROOT;
};
+ EC252E34CF52A70B4A836BDC = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = AudioPluginHost.entitlements;
+ path = AudioPluginHost.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
F14CDB17EFE157DA3C3A5A91 = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
C8B793AC1BEFBE7A99BE8352 = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
49453CC5AD9F08D2738464AC = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
8D1CA827F1EFD443BDCF198A = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
C9295196717FABE454A210B7 = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1\r
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1\r
\r
#include "BinaryData.h"\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
JUCEApplicationBase::quit();\r
}\r
\r
- void backButtonPressed() override\r
+ bool backButtonPressed() override\r
{\r
if (mainWindow->graphHolder != nullptr)\r
mainWindow->graphHolder->hideLastSidePanel();\r
+\r
+ return true;\r
}\r
\r
const String getApplicationName() override { return "Juce Plug-In Host"; }\r
if (auto* plugin = dynamic_cast<AudioPluginInstance*> (node->getProcessor()))\r
{\r
auto e = new XmlElement ("FILTER");\r
- e->setAttribute ("uid", (int) node->nodeID.uid);\r
- e->setAttribute ("x", node->properties ["x"].toString());\r
- e->setAttribute ("y", node->properties ["y"].toString());\r
+\r
+ e->setAttribute ("uid", (int) node->nodeID.uid);\r
+ e->setAttribute ("x", node->properties ["x"].toString());\r
+ e->setAttribute ("y", node->properties ["y"].toString());\r
+ #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE\r
+ e->setAttribute ("DPIAware", node->properties["DPIAware"].toString());\r
+ #endif\r
\r
for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)\r
{\r
node->getProcessor()->setStateInformation (m.getData(), (int) m.getSize());\r
}\r
\r
- node->properties.set ("x", xml.getDoubleAttribute ("x"));\r
- node->properties.set ("y", xml.getDoubleAttribute ("y"));\r
+ node->properties.set ("x", xml.getDoubleAttribute ("x"));\r
+ node->properties.set ("y", xml.getDoubleAttribute ("y"));\r
+ #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE\r
+ node->properties.set ("DPIAware", xml.getDoubleAttribute ("DPIAware"));\r
+ #endif\r
\r
for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)\r
{\r
case 10: showWindow (PluginWindow::Type::normal); break;\r
case 11: showWindow (PluginWindow::Type::programs); break;\r
case 12: showWindow (PluginWindow::Type::generic) ; break;\r
+ #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE\r
case 13:\r
{\r
if (auto* node = graph.graph.getNodeForId (pluginID))\r
node->properties.set ("DPIAware", ! node->properties ["DPIAware"]);\r
break;\r
}\r
+ #endif\r
case 14: showWindow (PluginWindow::Type::debug); break;\r
case 20: showWindow (PluginWindow::Type::audioIO); break;\r
case 21: testStateSaveLoad(); break;\r
<?xml version="1.0" encoding="UTF-8"?>\r
\r
<JUCERPROJECT id="3t6YqETY1" name="BinaryBuilder" projectType="consoleapp"\r
- juceFolder="../../../juce" jucerVersion="5.4.4" bundleIdentifier="com.roli.binarybuilder"\r
+ juceFolder="../../../juce" jucerVersion="5.4.5" bundleIdentifier="com.roli.binarybuilder"\r
displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd."\r
companyCopyright="ROLI Ltd.">\r
<EXPORTFORMATS>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = RecentFilesMenuTemplate.nib;
sourceTree = "SOURCE_ROOT";
};
+ 25C3A81567A43C28D8A9C143 = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = BinaryBuilder.entitlements;
+ path = BinaryBuilder.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
50B7C64414A3E778021F5EC4 = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c11;
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_core 1\r
\r
#include <juce_core/juce_core.h>\r
\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = ../../Source/SharedCanvas.h;
sourceTree = "SOURCE_ROOT";
};
+ 280A781618BDE3AF9BE15495 = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = NetworkGraphicsDemo.entitlements;
+ path = NetworkGraphicsDemo.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
2E13A899F4E3C99054A3656F = {
isa = PBXFileReference;
lastKnownFileType = wrapper.framework;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c11;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = ../../Source/SharedCanvas.h;
sourceTree = "SOURCE_ROOT";
};
+ 280A781618BDE3AF9BE15495 = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = NetworkGraphicsDemo.entitlements;
+ path = NetworkGraphicsDemo.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
2E13A899F4E3C99054A3656F = {
isa = PBXFileReference;
lastKnownFileType = wrapper.framework;
EE7498599191DDC73ECB55B0 = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
2E06386CE7CCA5FF76819BFF = {
isa = XCBuildConfiguration;
buildSettings = {
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
3BF0365A560ACD4FD24D40CE = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
9C6D2FD441D79104734762A5 = {
isa = XCBuildConfiguration;
buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1\r
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1\r
\r
#include "BinaryData.h"\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
<?xml version="1.0" encoding="UTF-8"?>\r
\r
<JUCERPROJECT id="gWI5Ir" name="NetworkGraphicsDemo" projectType="guiapp" bundleIdentifier="com.juce.NetworkGraphicsDemo"\r
- jucerVersion="5.4.4" displaySplashScreen="0" reportAppUsage="0"\r
+ jucerVersion="5.4.5" displaySplashScreen="0" reportAppUsage="0"\r
companyName="ROLI Ltd." companyCopyright="ROLI Ltd.">\r
<MAINGROUP id="OT9rJ2" name="NetworkGraphicsDemo">\r
<GROUP id="{48D54E6E-37F4-B20A-E038-C63E4EDFD4D9}" name="Source">\r
TARGET_ARCH := -march=native
endif
- JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.4 -DJUCE_APP_VERSION_HEX=0x50404 $(shell pkg-config --cflags x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
+ JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.5 -DJUCE_APP_VERSION_HEX=0x50405 $(shell pkg-config --cflags x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 -DJucePlugin_Build_Unity=0
JUCE_TARGET_APP := Projucer
TARGET_ARCH := -march=native
endif
- JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.4 -DJUCE_APP_VERSION_HEX=0x50404 $(shell pkg-config --cflags x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
+ JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.5 -DJUCE_APP_VERSION_HEX=0x50405 $(shell pkg-config --cflags x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 -DJucePlugin_Build_Unity=0
JUCE_TARGET_APP := Projucer
</dict>\r
</dict>\r
</dict>\r
+ <key>NSMicrophoneUsageDescription</key>\r
+ <string>This app requires audio input. If you do not have an audio interface connected it will use the built-in microphone.</string>\r
+ <key>NSCameraUsageDescription</key>\r
+ <string>This app requires access to the camera to function correctly.</string>\r
<key>CFBundleExecutable</key>\r
<string>${EXECUTABLE_NAME}</string>\r
<key>CFBundleIconFile</key>\r
<key>CFBundleSignature</key>\r
<string>????</string>\r
<key>CFBundleShortVersionString</key>\r
- <string>5.4.4</string>\r
+ <string>5.4.5</string>\r
<key>CFBundleVersion</key>\r
- <string>5.4.4</string>\r
+ <string>5.4.5</string>\r
<key>NSHumanReadableCopyright</key>\r
<string>ROLI Ltd.</string>\r
<key>NSHighResolutionCapable</key>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = "../../../../modules/juce_graphics";
sourceTree = "SOURCE_ROOT";
};
+ B7017BD3427B46FBAAAE448A = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = Projucer.entitlements;
+ path = Projucer.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
B8385E9A644BD3CD94876448 = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
"_DEBUG=1",
"DEBUG=1",
"JUCER_XCODE_MAC_F6D2F4CF=1",
- "JUCE_APP_VERSION=5.4.4",
- "JUCE_APP_VERSION_HEX=0x50404",
+ "JUCE_APP_VERSION=5.4.5",
+ "JUCE_APP_VERSION_HEX=0x50405",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
"_NDEBUG=1",
"NDEBUG=1",
"JUCER_XCODE_MAC_F6D2F4CF=1",
- "JUCE_APP_VERSION=5.4.4",
- "JUCE_APP_VERSION_HEX=0x50404",
+ "JUCE_APP_VERSION=5.4.5",
+ "JUCE_APP_VERSION_HEX=0x50405",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c11;
<Optimization>Disabled</Optimization>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile>\r
<Optimization>Full</Optimization>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
#include <windows.h>\r
\r
VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION 5,4,4,0\r
+FILEVERSION 5,4,5,0\r
BEGIN\r
BLOCK "StringFileInfo"\r
BEGIN\r
VALUE "CompanyName", "ROLI Ltd.\0"\r
VALUE "LegalCopyright", "ROLI Ltd.\0"\r
VALUE "FileDescription", "Projucer\0"\r
- VALUE "FileVersion", "5.4.4\0"\r
+ VALUE "FileVersion", "5.4.5\0"\r
VALUE "ProductName", "Projucer\0"\r
- VALUE "ProductVersion", "5.4.4\0"\r
+ VALUE "ProductVersion", "5.4.5\0"\r
END\r
END\r
\r
<Optimization>Disabled</Optimization>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile>\r
<Optimization>Full</Optimization>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
#include <windows.h>\r
\r
VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION 5,4,4,0\r
+FILEVERSION 5,4,5,0\r
BEGIN\r
BLOCK "StringFileInfo"\r
BEGIN\r
VALUE "CompanyName", "ROLI Ltd.\0"\r
VALUE "LegalCopyright", "ROLI Ltd.\0"\r
VALUE "FileDescription", "Projucer\0"\r
- VALUE "FileVersion", "5.4.4\0"\r
+ VALUE "FileVersion", "5.4.5\0"\r
VALUE "ProductName", "Projucer\0"\r
- VALUE "ProductVersion", "5.4.4\0"\r
+ VALUE "ProductVersion", "5.4.5\0"\r
END\r
END\r
\r
<Optimization>Disabled</Optimization>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
<ClCompile>\r
<Optimization>Full</Optimization>\r
<AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.4;JUCE_APP_VERSION_HEX=0x50404;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.5;JUCE_APP_VERSION_HEX=0x50405;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
<RuntimeTypeInfo>true</RuntimeTypeInfo>\r
<PrecompiledHeader/>\r
#include <windows.h>\r
\r
VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION 5,4,4,0\r
+FILEVERSION 5,4,5,0\r
BEGIN\r
BLOCK "StringFileInfo"\r
BEGIN\r
VALUE "CompanyName", "ROLI Ltd.\0"\r
VALUE "LegalCopyright", "ROLI Ltd.\0"\r
VALUE "FileDescription", "Projucer\0"\r
- VALUE "FileVersion", "5.4.4\0"\r
+ VALUE "FileVersion", "5.4.5\0"\r
VALUE "ProductName", "Projucer\0"\r
- VALUE "ProductVersion", "5.4.4\0"\r
+ VALUE "ProductVersion", "5.4.5\0"\r
END\r
END\r
\r
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_analytics 1\r
#define JUCE_MODULE_AVAILABLE_juce_core 1\r
\r
#include "BinaryData.h"\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
{\r
const char* const projectName = "Projucer";\r
const char* const companyName = "ROLI Ltd.";\r
- const char* const versionString = "5.4.4";\r
- const int versionNumber = 0x50404;\r
+ const char* const versionString = "5.4.5";\r
+ const int versionNumber = 0x50405;\r
}\r
#endif\r
<?xml version="1.0" encoding="UTF-8"?>\r
\r
<JUCERPROJECT id="M70qfTRRk" name="Projucer" projectType="guiapp" juceFolder="../../juce"\r
- jucerVersion="5.4.4" version="5.4.4" bundleIdentifier="com.juce.theprojucer"\r
+ jucerVersion="5.4.5" version="5.4.5" bundleIdentifier="com.juce.theprojucer"\r
splashScreenColour="Dark" displaySplashScreen="0" reportAppUsage="0"\r
companyName="ROLI Ltd." companyCopyright="ROLI Ltd." cppLanguageStandard="11">\r
<EXPORTFORMATS>\r
<XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK"\r
documentExtensions=".jucer" objCExtraSuffix="zkVtji" bigIcon="rv1F4h"\r
customPList="<plist> <dict> 	<key>NSAppTransportSecurity</key> 	<dict> 		<key>NSAllowsArbitraryLoads</key> 		<true/> 		<key>NSExceptionDomains</key> 		<dict> 			<key>amazonaws.com</key> 			<dict> 				<key>NSExceptionAllowsInsecureHTTPLoads</key> 				<true/> 				<key>NSIncludesSubdomains</key> 				<true/> 			</dict> 		</dict> 	</dict> </dict> </plist>"\r
- extraFrameworks="AudioUnit; Accelerate; AVFoundation; CoreAudio; CoreAudioKit; CoreMIDI; DiscRecording; QuartzCore; AudioToolbox; OpenGL; QTKit; QuickTime">\r
+ extraFrameworks="AudioUnit; Accelerate; AVFoundation; CoreAudio; CoreAudioKit; CoreMIDI; DiscRecording; QuartzCore; AudioToolbox; OpenGL; QTKit; QuickTime"\r
+ microphonePermissionNeeded="1" cameraPermissionNeeded="1">\r
<CONFIGURATIONS>\r
<CONFIGURATION name="Debug" isDebug="1" targetName="Projucer" cppLibType="libc++"\r
recommendedWarnings="LLVM"/>\r
auto leftSlice = bounds.removeFromLeft (150);\r
auto centreSlice = bounds;\r
\r
- //======================================================================\r
+ //==============================================================================\r
rightSlice.removeFromRight (20);\r
auto iconSlice = rightSlice.removeFromRight (100);\r
huckleberryLogoBounds = iconSlice.removeFromBottom (100).toFloat();\r
\r
- //======================================================================\r
+ //==============================================================================\r
juceLogoBounds = leftSlice.removeFromTop (150).toFloat();\r
juceLogoBounds.setWidth (juceLogoBounds.getWidth() + 100);\r
juceLogoBounds.setHeight (juceLogoBounds.getHeight() + 100);\r
\r
copyrightLabel.setBounds (leftSlice.removeFromBottom (20));\r
\r
- //======================================================================\r
+ //==============================================================================\r
auto titleHeight = 40;\r
\r
centreSlice.removeFromTop ((centreSlice.getHeight() / 2) - (titleHeight / 2));\r
\r
menu.addSubMenu ("Colour Scheme", colourSchemeMenu);\r
\r
- //==========================================================================\r
+ //==============================================================================\r
PopupMenu editorColourSchemeMenu;\r
\r
auto& appearanceSettings = getAppSettings().appearance;\r
}\r
}\r
\r
-//==========================================================================\r
+//==============================================================================\r
static File getJUCEExamplesDirectoryPathFromGlobal()\r
{\r
auto globalPath = File::createFileWithoutCheckingPath (getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString()\r
Analytics::getInstance()->logEvent ("Example Opened", data, ProjucerAnalyticsEvent::exampleEvent);\r
}\r
\r
-//==========================================================================\r
+//==============================================================================\r
static String getPlatformSpecificFileExtension()\r
{\r
#if JUCE_MAC\r
}\r
}\r
\r
-//==========================================================================\r
+//==============================================================================\r
void ProjucerApplication::handleMainMenuCommand (int menuItemID)\r
{\r
if (menuItemID >= recentProjectsBaseID && menuItemID < (recentProjectsBaseID + 100))\r
\r
r << " jassert (" << imageVariable << " != 0);\n"\r
<< " if (" << imageVariable << " != 0)\n"\r
- << " " << imageVariable << "->drawWithin (g, Rectangle<float> (x, y, width, height),\n"\r
+ << " " << imageVariable << "->drawWithin (g, Rectangle<int> (x, y, width, height).toFloat(),\n"\r
<< " " << String::repeatedString (" ", imageVariable.length() + 18)\r
<< (mode == stretched ? "RectanglePlacement::stretchToFit"\r
: (mode == proportionalReducingOnly ? "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize"\r
Project& project;\r
ValueTree exportersTree;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void valueTreeChildAdded (ValueTree& parentTree, ValueTree&) override { refreshIfNeeded (parentTree); }\r
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int) override { refreshIfNeeded (parentTree); }\r
void valueTreeChildOrderChanged (ValueTree& parentTree, int, int) override { refreshIfNeeded (parentTree); }\r
\r
Rectangle<int> textBounds;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
String getErrorMessage()\r
{\r
showDownloadButton = false;\r
#pragma once\r
\r
\r
-//==========================================================================\r
+//==============================================================================\r
struct ProjectSettingsComponent : public Component,\r
private ChangeListener\r
{\r
#include "../../LiveBuildEngine/jucer_DiagnosticMessage.h"\r
#include "../../LiveBuildEngine/jucer_CompileEngineClient.h"\r
\r
-//======================================================================\r
+//==============================================================================\r
HeaderComponent::HeaderComponent()\r
{\r
addAndMakeVisible (configLabel);\r
}\r
}\r
\r
-//======================================================================\r
+//==============================================================================\r
void HeaderComponent::resized()\r
{\r
auto bounds = getLocalBounds();\r
configLabel.setFont ({ bounds.getHeight() / 3.0f });\r
\r
- //======================================================================\r
+ //==============================================================================\r
{\r
auto headerBounds = bounds.removeFromLeft (tabsWidth);\r
\r
projectNameLabel.setBounds (headerBounds);\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
auto exporterWidth = jmin (400, bounds.getWidth() / 2);\r
Rectangle<int> exporterBounds (0, 0, exporterWidth, bounds.getHeight());\r
\r
runAppButton->getWidth(), runAppButton->getHeight());\r
}\r
\r
-//======================================================================\r
+//==============================================================================\r
void HeaderComponent::setCurrentProject (Project* p) noexcept\r
{\r
project = p;\r
}\r
}\r
\r
-//======================================================================\r
+//==============================================================================\r
void HeaderComponent::updateExporters() noexcept\r
{\r
auto selectedName = getSelectedExporterName();\r
return false;\r
}\r
\r
-//======================================================================\r
+//==============================================================================\r
int HeaderComponent::getUserButtonWidth() const noexcept\r
{\r
return userSettingsButton->getWidth();\r
resized();\r
}\r
\r
-//======================================================================\r
+//==============================================================================\r
void HeaderComponent::showUserSettings() noexcept\r
{\r
#if JUCER_ENABLE_GPL_MODE\r
userSettingsWindow = &CallOutBox::launchAsynchronously (content, userSettingsButton->getScreenBounds(), nullptr);\r
}\r
\r
-//==========================================================================\r
+//==============================================================================\r
void HeaderComponent::lookAndFeelChanged()\r
{\r
if (userSettingsWindow != nullptr)\r
repaint();\r
}\r
\r
-//======================================================================\r
+//==============================================================================\r
static void sendProjectButtonAnalyticsEvent (StringRef label)\r
{\r
StringPairArray data;\r
}\r
}\r
\r
-//======================================================================\r
+//==============================================================================\r
void HeaderComponent::buildPing()\r
{\r
if (! isTimerRunning())\r
HeaderComponent();\r
~HeaderComponent() override;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void resized() override;\r
void paint (Graphics&) override;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void setCurrentProject (Project*) noexcept;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void updateExporters() noexcept;\r
String getSelectedExporterName() const noexcept;\r
bool canCurrentExporterLaunchProject() const noexcept;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
int getUserButtonWidth() const noexcept;\r
void sidebarTabsWidthChanged (int newWidth) noexcept;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void showUserSettings() noexcept;\r
\r
private:\r
- //==========================================================================\r
+ //==============================================================================\r
void lookAndFeelChanged() override;\r
void changeListenerCallback (ChangeBroadcaster* source) override;\r
void valueChanged (Value&) override;\r
void timerCallback() override;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void valueTreeChildAdded (ValueTree& parentTree, ValueTree&) override { updateIfNeeded (parentTree); }\r
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int) override { updateIfNeeded (parentTree); }\r
void valueTreeChildOrderChanged (ValueTree& parentTree, int, int) override { updateIfNeeded (parentTree); }\r
updateExporters();\r
}\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void initialiseButtons() noexcept;\r
\r
void updateName() noexcept;\r
void updateExporterButton() noexcept;\r
void updateUserAvatar() noexcept;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void buildPing();\r
void buildFinished (bool);\r
void setRunAppButtonState (bool);\r
\r
- //==========================================================================\r
+ //==============================================================================\r
int tabsWidth = 200;\r
bool isBuilding = false;\r
\r
bounds.removeFromLeft (5);\r
g.setColour (rowIsSelected ? findColour (defaultHighlightedTextColourId) : findColour (widgetTextColourId));\r
\r
- //======================================================================\r
+ //==============================================================================\r
auto moduleID = project.getEnabledModules().getModuleID (rowNumber);\r
\r
g.drawFittedText (moduleID, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (0) * width)), Justification::centredLeft, 1);\r
\r
- //======================================================================\r
+ //==============================================================================\r
auto version = project.getEnabledModules().getModuleInfo (moduleID).getVersion();\r
if (version.isEmpty())\r
version = "?";\r
\r
g.drawFittedText (version, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (1) * width)), Justification::centredLeft, 1);\r
\r
- //======================================================================\r
+ //==============================================================================\r
auto copyLocally = project.getEnabledModules().shouldCopyModuleFilesLocally (moduleID).getValue() ? "Yes" : "No";\r
\r
g.drawFittedText (copyLocally, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (2) * width)), Justification::centredLeft, 1);\r
\r
- //======================================================================\r
+ //==============================================================================\r
String pathText;\r
\r
if (project.getEnabledModules().shouldUseGlobalPath (moduleID))\r
addAndMakeVisible (sidebarTabs);\r
createProjectTabs();\r
\r
- //======================================================================\r
+ //==============================================================================\r
auto& settings = project->getStoredProperties();\r
\r
auto lastTreeWidth = settings.getValue ("projectPanelWidth").getIntValue();\r
projectTab->setPanelHeightProportion (i, settings.getValue ("projectTabPanelHeight" + String (i), "1")\r
.getFloatValue());\r
\r
- //======================================================================\r
+ //==============================================================================\r
resizerBar.reset (new ResizableEdgeComponent (&sidebarTabs, &sidebarSizeConstrainer,\r
ResizableEdgeComponent::rightEdge));\r
addAndMakeVisible (resizerBar.get());\r
"Include BinaryData.h in the JuceHeader.h file");\r
\r
props.add (new TextPropertyComponent (binaryDataNamespaceValue, "BinaryData Namespace", 256, false),\r
- "The namespace containing the binary assests.");\r
+ "The namespace containing the binary assets.");\r
\r
props.add (new ChoicePropertyComponent (cppStandardValue, "C++ Language Standard",\r
{ "C++11", "C++14", "C++17", "Use Latest" },\r
\r
if (cppStandard == "11") // VS doesn't support the C++11 flag so we have to bump it to C++14\r
cppStandard = "14";\r
- else if (cppStandard == "17") // nor does it support the C++17 flag, so we'll just use latest for now until it's added\r
- cppStandard = "latest";\r
\r
cl->createNewChildElement ("LanguageStandard")->addTextElement ("stdcpp" + cppStandard);\r
}\r
cameraPermissionNeededValue (settings, Ids::cameraPermissionNeeded, getUndoManager()),\r
cameraPermissionTextValue (settings, Ids::cameraPermissionText, getUndoManager(),\r
"This app requires access to the camera to function correctly."),\r
+ iosBluetoothPermissionNeededValue (settings, Ids::iosBluetoothPermissionNeeded, getUndoManager()),\r
+ iosBluetoothPermissionTextValue (settings, Ids::iosBluetoothPermissionText, getUndoManager(),\r
+ "This app requires access to Bluetooth to function correctly."),\r
uiFileSharingEnabledValue (settings, Ids::UIFileSharingEnabled, getUndoManager()),\r
uiSupportsDocumentBrowserValue (settings, Ids::UISupportsDocumentBrowser, getUndoManager()),\r
uiStatusBarHiddenValue (settings, Ids::UIStatusBarHidden, getUndoManager()),\r
bool isCameraPermissionEnabled() const { return cameraPermissionNeededValue.get(); }\r
String getCameraPermissionTextString() const { return cameraPermissionTextValue.get(); }\r
\r
+ bool isBluetoothPermissionEnabled() const { return iosBluetoothPermissionNeededValue.get(); }\r
+ String getBluetoothPermissionTextString() const { return iosBluetoothPermissionTextValue.get(); }\r
+\r
bool isInAppPurchasesEnabled() const { return iosInAppPurchasesValue.get(); }\r
bool isBackgroundAudioEnabled() const { return iosBackgroundAudioValue.get(); }\r
bool isBackgroundBleEnabled() const { return iosBackgroundBleValue.get(); }\r
\r
bool shouldKeepCustomXcodeSchemes() const { return keepCustomXcodeSchemesValue.get(); }\r
\r
- String getIosDevelopmentTeamIDString() const { return iosDevelopmentTeamIDValue.get(); }\r
+ String getDevelopmentTeamIDString() const { return iosDevelopmentTeamIDValue.get(); }\r
String getAppGroupIdString() const { return iosAppGroupsIDValue.get(); }\r
\r
String getDefaultLaunchStoryboardName() const { jassert (iOS); return "LaunchScreen"; }\r
"Camera Access Text", 1024, false),\r
"A short description of why your app requires camera access.");\r
\r
+ if (iOS)\r
+ {\r
+ props.add (new ChoicePropertyComponent (iosBluetoothPermissionNeededValue, "Bluetooth Access"),\r
+ "Enable this to allow your app to use Bluetooth on iOS 13.0 and above. "\r
+ "The user of your app will be prompted to grant Bluetooth access permissions.");\r
+\r
+ props.add (new TextPropertyComponentWithEnablement (iosBluetoothPermissionTextValue, iosBluetoothPermissionNeededValue,\r
+ "Bluetooth Access Text", 1024, false),\r
+ "A short description of why your app requires Bluetooth access.");\r
+ }\r
+\r
props.add (new ChoicePropertyComponent (iosInAppPurchasesValue, "In-App Purchases Capability"),\r
"Enable this to grant your app the capability for in-app purchases. "\r
"This option requires that you specify a valid Development Team ID.");\r
"This is useful if you want to use different bundle identifiers for Mac and iOS exporters in the same project.");\r
\r
props.add (new TextPropertyComponent (iosDevelopmentTeamIDValue, "Development Team ID", 10, false),\r
- "The Development Team ID to be used for setting up code-signing your iOS app. This is a ten-character "\r
+ "The Development Team ID to be used for setting up code-signing your app. This is a ten-character "\r
"string (for example, \"S7B6T5XJ2Q\") that describes the distribution certificate Apple issued to you. "\r
"You can find this string in the OS X app Keychain Access under \"Certificates\".");\r
\r
osxArchitecture (config, Ids::osxArchitecture, getUndoManager(), osxArch_Default),\r
customXcodeFlags (config, Ids::customXcodeFlags, getUndoManager()),\r
plistPreprocessorDefinitions (config, Ids::plistPreprocessorDefinitions, getUndoManager()),\r
- codeSignIdentity (config, Ids::codeSigningIdentity, getUndoManager(), iOS ? "iPhone Developer" : "Mac Developer"),\r
+ codeSignIdentity (config, Ids::codeSigningIdentity, getUndoManager()),\r
fastMathEnabled (config, Ids::fastMath, getUndoManager()),\r
stripLocalSymbolsEnabled (config, Ids::stripLocalSymbols, getUndoManager()),\r
pluginBinaryCopyStepEnabled (config, Ids::enablePluginBinaryCopyStep, getUndoManager(), true),\r
optimisationLevelValue.setDefault (isDebug() ? gccO0 : gccO3);\r
}\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void createConfigProperties (PropertyListBuilder& props) override\r
{\r
addXcodePluginInstallPathProperties (props);\r
return "${CURRENT_ARCH}";\r
}\r
\r
- //==========================================================================\r
+ //==============================================================================\r
String getOSXArchitectureString() const { return osxArchitecture.get(); }\r
String getPListPreprocessorDefinitionsString() const { return plistPreprocessorDefinitions.get(); }\r
\r
String getOSXDeploymentTargetString() const { return osxDeploymentTarget.get(); }\r
\r
String getCodeSignIdentityString() const { return codeSignIdentity.get(); }\r
- bool isUsingDefaultCodeSignIdentity() const { return codeSignIdentity.isUsingDefault(); }\r
\r
String getiOSDeploymentTargetString() const { return iosDeploymentTarget.get(); }\r
\r
String getUnityPluginBinaryLocationString() const { return unityPluginBinaryLocation.get(); }\r
\r
private:\r
- //==========================================================================\r
+ //==============================================================================\r
bool iOS;\r
\r
ValueWithDefault osxSDKVersion, osxDeploymentTarget, iosDeploymentTarget, osxArchitecture,\r
vstBinaryLocation, vst3BinaryLocation, auBinaryLocation, rtasBinaryLocation,\r
aaxBinaryLocation, unityPluginBinaryLocation;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void addXcodePluginInstallPathProperties (PropertyListBuilder& props)\r
{\r
auto isBuildingAnyPlugins = (project.shouldBuildVST() || project.shouldBuildVST3() || project.shouldBuildAU()\r
{\r
auto attributes = getID() + " = { ";\r
\r
- auto developmentTeamID = owner.getIosDevelopmentTeamIDString();\r
+ auto developmentTeamID = owner.getDevelopmentTeamIDString();\r
\r
if (developmentTeamID.isNotEmpty())\r
{\r
if (owner.iOS)\r
{\r
s.set ("ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon");\r
- s.set ("ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME", "LaunchImage");\r
+\r
+ if (! owner.shouldAddStoryboardToProject())\r
+ s.set ("ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME", "LaunchImage");\r
}\r
else\r
{\r
s.set ("GCC_VERSION", gccVersion);\r
s.set ("CLANG_LINK_OBJC_RUNTIME", "NO");\r
\r
- if (isUsingCodeSigning (config))\r
- {\r
- s.set (owner.iOS ? "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"" : "CODE_SIGN_IDENTITY",\r
- config.getCodeSignIdentityString().quoted());\r
+ auto codeSigningIdentity = owner.getCodeSigningIdentity (config);\r
+ s.set (owner.iOS ? "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"" : "CODE_SIGN_IDENTITY",\r
+ codeSigningIdentity.quoted());\r
+\r
+ if (codeSigningIdentity.isNotEmpty())\r
s.set ("PROVISIONING_PROFILE_SPECIFIER", "\"\"");\r
- }\r
\r
- if (owner.getIosDevelopmentTeamIDString().isNotEmpty())\r
- s.set ("DEVELOPMENT_TEAM", owner.getIosDevelopmentTeamIDString());\r
+ if (owner.getDevelopmentTeamIDString().isNotEmpty())\r
+ s.set ("DEVELOPMENT_TEAM", owner.getDevelopmentTeamIDString());\r
\r
if (shouldAddEntitlements())\r
s.set ("CODE_SIGN_ENTITLEMENTS", owner.getEntitlementsFileName().quoted());\r
}\r
}\r
\r
- flags.add (owner.replacePreprocessorTokens (config, owner.getExtraLinkerFlagsString()));\r
flags.add (owner.getExternalLibraryFlags (config));\r
\r
auto libs = owner.xcodeLibs;\r
flags.add (getLinkerFlagForLib (l));\r
}\r
\r
+ flags.add (owner.replacePreprocessorTokens (config, owner.getExtraLinkerFlagsString()));\r
flags = getCleanedStringArray (flags);\r
}\r
\r
\r
if (owner.iOS)\r
{\r
+ if (owner.isBluetoothPermissionEnabled())\r
+ {\r
+ addPlistDictionaryKey (dict, "NSBluetoothAlwaysUsageDescription", owner.getBluetoothPermissionTextString());\r
+ addPlistDictionaryKey (dict, "NSBluetoothPeripheralUsageDescription", owner.getBluetoothPermissionTextString()); // needed for pre iOS 13.0\r
+ }\r
+\r
addPlistDictionaryKeyBool (dict, "LSRequiresIPhoneOS", true);\r
\r
if (type != AudioUnitv3PlugIn)\r
return {};\r
}\r
\r
- bool isUsingCodeSigning (const XcodeBuildConfiguration& config) const\r
- {\r
- return (! config.isUsingDefaultCodeSignIdentity())\r
- || owner.getIosDevelopmentTeamIDString().isNotEmpty();\r
- }\r
-\r
//==============================================================================\r
const XcodeProjectExporter& owner;\r
\r
iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue,\r
appSandboxValue, appSandboxOptionsValue,\r
hardenedRuntimeValue, hardenedRuntimeOptionsValue,\r
- microphonePermissionNeededValue, microphonePermissionsTextValue, cameraPermissionNeededValue, cameraPermissionTextValue,\r
+ microphonePermissionNeededValue, microphonePermissionsTextValue, cameraPermissionNeededValue, cameraPermissionTextValue, iosBluetoothPermissionNeededValue, iosBluetoothPermissionTextValue,\r
uiFileSharingEnabledValue, uiSupportsDocumentBrowserValue, uiStatusBarHiddenValue, documentExtensionsValue, iosInAppPurchasesValue,\r
iosBackgroundAudioValue, iosBackgroundBleValue, iosPushNotificationsValue, iosAppGroupsValue, iCloudPermissionsValue,\r
iosDevelopmentTeamIDValue, iosAppGroupsIDValue, keepCustomXcodeSchemesValue, useHeaderMapValue, customLaunchStoryboardValue,\r
\r
void addFilesAndGroupsToProject (StringArray& topLevelGroupIDs) const\r
{\r
- auto entitlements = getEntitlements();\r
-\r
- if (entitlements.size() > 0)\r
- topLevelGroupIDs.add (addEntitlementsFile (entitlements));\r
+ addEntitlementsFile();\r
\r
for (auto& group : getAllGroups())\r
{\r
return sanitisePath (searchPath);\r
}\r
\r
+ String getCodeSigningIdentity (const XcodeBuildConfiguration& config) const\r
+ {\r
+ auto identity = config.getCodeSignIdentityString();\r
+\r
+ if (identity.isEmpty() && getDevelopmentTeamIDString().isNotEmpty())\r
+ return iOS ? "iPhone Developer" : "Mac Developer";\r
+\r
+ return identity;\r
+ }\r
+\r
StringPairArray getProjectSettings (const XcodeBuildConfiguration& config) const\r
{\r
StringPairArray s;\r
s.set ("ONLY_ACTIVE_ARCH", "YES");\r
}\r
\r
+ s.set (iOS ? "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"" : "CODE_SIGN_IDENTITY",\r
+ getCodeSigningIdentity (config).quoted());\r
+\r
if (iOS)\r
{\r
- s.set ("\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"", config.getCodeSignIdentityString().quoted());\r
s.set ("SDKROOT", "iphoneos");\r
s.set ("TARGETED_DEVICE_FAMILY", getDeviceFamilyString().quoted());\r
s.set ("IPHONEOS_DEPLOYMENT_TARGET", config.getiOSDeploymentTargetString());\r
}\r
- else\r
- {\r
- if (! config.isUsingDefaultCodeSignIdentity() || getIosDevelopmentTeamIDString().isNotEmpty())\r
- s.set ("CODE_SIGN_IDENTITY", config.getCodeSignIdentityString().quoted());\r
- }\r
\r
s.set ("ZERO_LINK", "NO");\r
\r
return entitlements;\r
}\r
\r
- String addEntitlementsFile (StringPairArray entitlements) const\r
+ String addEntitlementsFile() const\r
{\r
String content =\r
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"\r
"<plist version=\"1.0\">\n"\r
"<dict>\n";\r
\r
+ auto entitlements = getEntitlements();\r
auto keys = entitlements.getAllKeys();\r
\r
for (auto& key : keys)\r
<< newLine\r
<< "// END SECTION A" << newLine\r
<< newLine\r
- << "#define JUCE_USE_DARK_SPLASH_SCREEN " << (project.getSplashScreenColourString() == "Dark" ? "1" : "0") << newLine;\r
+ << "#define JUCE_USE_DARK_SPLASH_SCREEN " << (project.getSplashScreenColourString() == "Dark" ? "1" : "0") << newLine\r
+ << newLine\r
+ << "#define JUCE_PROJUCER_VERSION 0x" << String::toHexString (ProjectInfo::versionNumber) << newLine;\r
\r
out << newLine\r
<< "//==============================================================================" << newLine;\r
out << CodeHelpers::createIncludeStatement (project.getBinaryDataHeaderFile(), appConfigFile) << newLine;\r
\r
out << newLine\r
+ << "#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION" << newLine\r
+ << " /** If you've hit this error then the version of the Projucer that was used to generate this project is" << newLine\r
+ << " older than the version of the JUCE modules being included. To fix this error, re-save your project" << newLine\r
+ << " using the latest version of the Projucer or, if you aren't using the Projucer to manage your project," << newLine\r
+ << " remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file." << newLine\r
+ << " */" << newLine\r
+ << " #error \"This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error.\"" << newLine\r
+ << "#endif" << newLine\r
+ << newLine\r
<< "#if ! DONT_SET_USING_JUCE_NAMESPACE" << newLine\r
<< " // If your code uses a lot of JUCE classes, then this will obviously save you" << newLine\r
<< " // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE." << newLine\r
DECLARE_ID (iCloudPermissions);\r
DECLARE_ID (iosDevelopmentTeamID);\r
DECLARE_ID (iosAppGroupsId);\r
+ DECLARE_ID (iosBluetoothPermissionNeeded);\r
+ DECLARE_ID (iosBluetoothPermissionText);\r
DECLARE_ID (duplicateAppExResourcesFolder);\r
DECLARE_ID (buildToolsVersion);\r
DECLARE_ID (gradleVersion);\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+</dict>
+</plist>
path = System/Library/Frameworks/CoreMedia.framework;
sourceTree = SDKROOT;
};
+ 911BC81C9C4E07C2E2FD68C1 = {
+ isa = PBXFileReference;
+ lastKnownFileType = text.plist.xml;
+ name = UnitTestRunner.entitlements;
+ path = UnitTestRunner.entitlements;
+ sourceTree = "SOURCE_ROOT";
+ };
9514F6D920549F8A44B2E332 = {
isa = PBXFileReference;
lastKnownFileType = file;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_LINK_OBJC_RUNTIME = NO;
+ CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c11;
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm">\r
<Filter>JUCE Modules\juce_data_structures</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <Filter>JUCE Modules\juce_dsp\containers</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<Filter>JUCE Modules\juce_dsp\containers</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <ExcludedFromBuild>true</ExcludedFromBuild>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<ExcludedFromBuild>true</ExcludedFromBuild>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockImplementation.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_BlockSerialReader.cpp">\r
+ <Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_blocks_basics\topology\internal\juce_ConnectedDeviceGroup.cpp">\r
<Filter>JUCE Modules\juce_blocks_basics\topology\internal</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm">\r
<Filter>JUCE Modules\juce_data_structures</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp">\r
+ <Filter>JUCE Modules\juce_dsp\containers</Filter>\r
+ </ClCompile>\r
<ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp">\r
<Filter>JUCE Modules\juce_dsp\containers</Filter>\r
</ClCompile>\r
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_analytics 1\r
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1\r
#include <juce_video/juce_video.h>\r
\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
<?xml version="1.0" encoding="UTF-8"?>\r
\r
<JUCERPROJECT id="Z2Xzcp" name="UnitTestRunner" projectType="consoleapp" bundleIdentifier="com.roli.UnitTestRunner"\r
- jucerVersion="5.4.4" defines="JUCE_UNIT_TESTS=1" displaySplashScreen="0"\r
+ jucerVersion="5.4.5" defines="JUCE_UNIT_TESTS=1" displaySplashScreen="0"\r
reportAppUsage="0" companyName="ROLI Ltd." companyCopyright="ROLI Ltd.">\r
<MAINGROUP id="GZdWCU" name="UnitTestRunner">\r
<GROUP id="{22894462-E1A9-036F-ED94-B51A50C87552}" name="Source">\r
\r
#define JUCE_USE_DARK_SPLASH_SCREEN 1\r
\r
+#define JUCE_PROJUCER_VERSION 0x50405\r
+\r
//==============================================================================\r
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1\r
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1\r
#include <juce_video/juce_video.h>\r
\r
\r
+#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION\r
+ /** If you've hit this error then the version of the Projucer that was used to generate this project is\r
+ older than the version of the JUCE modules being included. To fix this error, re-save your project\r
+ using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,\r
+ remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file.\r
+ */\r
+ #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."\r
+#endif\r
+\r
#if ! DONT_SET_USING_JUCE_NAMESPACE\r
// If your code uses a lot of JUCE classes, then this will obviously save you\r
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.\r
<?xml version="1.0" encoding="UTF-8"?>\r
\r
<JUCERPROJECT id="IvabE4" name="WindowsDLL" projectType="library" juceLinkage="none"\r
- bundleIdentifier="com.roli.jucedll" jucerVersion="5.4.4" defines="JUCE_DLL_BUILD=1"\r
+ bundleIdentifier="com.roli.jucedll" jucerVersion="5.4.5" defines="JUCE_DLL_BUILD=1"\r
displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd."\r
companyCopyright="ROLI Ltd.">\r
<EXPORTFORMATS>\r
"i386", for example).\r
\r
Visual Studio:\r
- VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio\r
+ libs/VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio\r
release, arch is the target architecture in Visual Studio ("x64" or "Win32", for example), and\r
{runtime} is the type of the run-time library indicated by the corresponding compiler flag\r
("MD", "MDd", "MT", "MTd").\r
\r
ID: juce_analytics\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE analytics classes\r
description: Classes to collect analytics and send to destinations\r
website: http://www.juce.com/juce\r
\r
ID: juce_audio_basics\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE audio and MIDI data classes\r
description: Classes for audio buffer manipulation, midi message handling, synthesis, etc.\r
website: http://www.juce.com/juce\r
CatmullRomInterpolator() noexcept;\r
~CatmullRomInterpolator() noexcept;\r
\r
+ CatmullRomInterpolator (CatmullRomInterpolator&&) noexcept = default;\r
+ CatmullRomInterpolator& operator= (CatmullRomInterpolator&&) noexcept = default;\r
+\r
/** Resets the state of the interpolator.\r
Call this when there's a break in the continuity of the input data stream.\r
*/\r
LagrangeInterpolator() noexcept;\r
~LagrangeInterpolator() noexcept;\r
\r
+ LagrangeInterpolator (LagrangeInterpolator&&) noexcept = default;\r
+ LagrangeInterpolator& operator= (LagrangeInterpolator&&) noexcept = default;\r
+\r
/** Resets the state of the interpolator.\r
Call this when there's a break in the continuity of the input data stream.\r
*/\r
\r
void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd)\r
{\r
- for (auto& device : MidiInput::getAvailableDevices())\r
+ if (name.isEmpty())\r
{\r
- if (device.name == name)\r
+ addMidiInputDeviceCallback ({}, callbackToAdd);\r
+ }\r
+ else\r
+ {\r
+ for (auto& device : MidiInput::getAvailableDevices())\r
{\r
- addMidiInputDeviceCallback (device.identifier, callbackToAdd);\r
- return;\r
+ if (device.name == name)\r
+ {\r
+ addMidiInputDeviceCallback (device.identifier, callbackToAdd);\r
+ return;\r
+ }\r
}\r
}\r
}\r
installed, or you've not got your paths set up correctly to find its header\r
files.\r
*/\r
- #include <rtdk.h>\r
#include <Bela.h>\r
#include <Midi.h>\r
#endif\r
\r
ID: juce_audio_devices\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE audio and MIDI I/O device classes\r
description: Classes to play and record from audio and MIDI I/O devices\r
website: http://www.juce.com/juce\r
}\r
\r
private:\r
- //=============================================================================\r
+ //==============================================================================\r
void* (*threadEntryProc) (void*) = nullptr;\r
void* threadUserPtr = nullptr;\r
\r
SlRef<SLEngineItf_> engine;\r
};\r
\r
+OpenSLEngineHolder& getEngineHolder()\r
+{\r
+ static OpenSLEngineHolder holder;\r
+ return holder;\r
+}\r
+\r
//==============================================================================\r
class SLRealtimeThread;\r
\r
\r
SLObjectItf obj = nullptr;\r
\r
- SharedResourcePointer<OpenSLEngineHolder> holder;\r
+ auto& holder = getEngineHolder();\r
\r
- if (auto e = *holder->engine)\r
+ if (auto e = *holder.engine)\r
{\r
- auto status = e->CreateAudioPlayer (holder->engine, &obj, &source, &sink, 2,\r
+ auto status = e->CreateAudioPlayer (holder.engine, &obj, &source, &sink, 2,\r
queueInterfaces, interfaceRequired);\r
\r
if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize(obj, 0) != SL_RESULT_SUCCESS)\r
\r
SLObjectItf obj = nullptr;\r
\r
- SharedResourcePointer<OpenSLEngineHolder> holder;\r
+ auto& holder = getEngineHolder();\r
\r
- if (auto e = *holder->engine)\r
+ if (auto e = *holder.engine)\r
{\r
- auto status = e->CreateAudioRecorder (holder->engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired);\r
+ auto status = e->CreateAudioRecorder (holder.engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired);\r
\r
if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS)\r
{\r
\r
if (outputChannels > 0)\r
{\r
- SharedResourcePointer<OpenSLEngineHolder> holder;\r
+ auto& holder = getEngineHolder();\r
SLObjectItf obj = nullptr;\r
- auto err = (*holder->engine)->CreateOutputMix (holder->engine, &obj, 0, nullptr, nullptr);\r
+\r
+ auto err = (*holder.engine)->CreateOutputMix (holder.engine, &obj, 0, nullptr, nullptr);\r
\r
if (err != SL_RESULT_SUCCESS || obj == nullptr || *obj == nullptr\r
|| (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS)\r
outputLatency = (int) ((longestLatency * outputLatency) / totalLatency) & ~15;\r
\r
// You can only create this class if you are sure that your hardware supports OpenSL\r
- jassert (engineHolder->slLibrary.getNativeHandle() != nullptr);\r
+ jassert (getEngineHolder().slLibrary.getNativeHandle() != nullptr);\r
}\r
\r
~OpenSLAudioIODevice() override\r
friend class SLRealtimeThread;\r
\r
//==============================================================================\r
- SharedResourcePointer<OpenSLEngineHolder> engineHolder;\r
-\r
int actualBufferSize = 0, sampleRate = 0, audioBuffersToEnqueue = 0;\r
int inputLatency, outputLatency;\r
bool deviceOpen = false, audioProcessingEnabled = true;\r
}\r
\r
private:\r
- //=============================================================================\r
+ //==============================================================================\r
static void staticFinished (SLAndroidSimpleBufferQueueItf, void* context)\r
{\r
static_cast<SLRealtimeThread*> (context)->finished();\r
}\r
\r
- //=============================================================================\r
+ //==============================================================================\r
DynamicLibrary slLibrary { "libOpenSLES.so" };\r
\r
SlRef<SLEngineItf_> engine;\r
\r
void poll()\r
{\r
- int receivedBytes = 0;\r
+ size_t receivedBytes = 0;\r
\r
for (;;)\r
{\r
\r
if (receivedBytes == buffer.size())\r
{\r
- pushMidiData (receivedBytes);\r
+ pushMidiData (static_cast<int> (receivedBytes));\r
receivedBytes = 0;\r
}\r
}\r
return devices;\r
}\r
\r
+ void pushMidiMessage (juce::MidiMessage& message)\r
+ {\r
+ concatenator.pushMidiData (message.getRawData(), message.getRawDataSize(), Time::getMillisecondCounter() * 0.001, midiInput, *midiCallback);\r
+ }\r
+\r
private:\r
void pushMidiData (int length)\r
{\r
\r
auto subCount = snd_rawmidi_info_get_subdevices_count (info);\r
\r
- for (int sub = 0; sub < subCount; ++sub)\r
+ for (size_t sub = 0; sub < subCount; ++sub)\r
{\r
snd_rawmidi_info_set_subdevice (info, sub);\r
\r
snd_ctl_close (ctl);\r
}\r
\r
- String midiPort;\r
MidiInput* const midiInput;\r
+ String midiPort;\r
MidiInputCallback* const midiCallback;\r
\r
Midi midi;\r
}\r
\r
//==============================================================================\r
- StringArray getOutputChannelNames() override { return { "Out #1", "Out #2" }; }\r
- StringArray getInputChannelNames() override { return { "In #1", "In #2" }; }\r
+ StringArray getOutputChannelNames() override\r
+ {\r
+ StringArray result;\r
+\r
+ for (int i = 1; i <= actualNumberOfOutputs; i++)\r
+ result.add ("Out #" + std::to_string (i));\r
+\r
+ return result;\r
+ }\r
+\r
+ StringArray getInputChannelNames() override\r
+ {\r
+ StringArray result;\r
+\r
+ for (int i = 1; i <= actualNumberOfInputs; i++)\r
+ result.add ("In #" + std::to_string (i));\r
+\r
+ return result;\r
+ }\r
+\r
Array<double> getAvailableSampleRates() override { return { 44100.0 }; }\r
Array<int> getAvailableBufferSizes() override { /* TODO: */ return { getDefaultBufferSize() }; }\r
int getDefaultBufferSize() override { return defaultSettings.periodSize; }\r
auto numIns = getNumContiguousSetBits (inputChannels);\r
auto numOuts = getNumContiguousSetBits (outputChannels);\r
\r
- settings.useAnalog = 0;\r
- settings.useDigital = 0;\r
- settings.numAudioInChannels = numIns;\r
- settings.numAudioOutChannels = numOuts;\r
+ // Input and Output channels are numbered as follows\r
+ //\r
+ // 0 .. 1 - audio\r
+ // 2 .. 9 - analog\r
+\r
+ if (numIns > 2 || numOuts > 2)\r
+ {\r
+ settings.useAnalog = true;\r
+ settings.numAnalogInChannels = std::max (numIns - 2, 8);\r
+ settings.numAnalogOutChannels = std::max (numOuts - 2, 8);\r
+ settings.uniformSampleRate = true;\r
+ }\r
+\r
+ settings.numAudioInChannels = std::max (numIns, 2);\r
+ settings.numAudioOutChannels = std::max (numOuts, 2);\r
+\r
settings.detectUnderruns = 1;\r
settings.setup = setupCallback;\r
settings.render = renderCallback;\r
settings.cleanup = cleanupCallback;\r
- settings.interleave = 1;\r
+ settings.interleave = 0;\r
\r
if (bufferSizeSamples > 0)\r
settings.periodSize = bufferSizeSamples;\r
actualNumberOfInputs = jmin (numIns, actualNumberOfInputs);\r
actualNumberOfOutputs = jmin (numOuts, actualNumberOfOutputs);\r
\r
- audioInBuffer.setSize (actualNumberOfInputs, actualBufferSize);\r
channelInBuffer.calloc (actualNumberOfInputs);\r
-\r
- audioOutBuffer.setSize (actualNumberOfOutputs, actualBufferSize);\r
channelOutBuffer.calloc (actualNumberOfOutputs);\r
\r
return {};\r
actualNumberOfInputs = 0;\r
actualNumberOfOutputs = 0;\r
\r
- audioInBuffer.setSize (0, 0);\r
channelInBuffer.free();\r
-\r
- audioOutBuffer.setSize (0, 0);\r
channelOutBuffer.free();\r
}\r
}\r
}\r
else\r
{\r
- audioInBuffer.clear();\r
- audioOutBuffer.clear();\r
-\r
callback = newCallback;\r
isRunning = (Bela_startAudio() == 0);\r
\r
//==============================================================================\r
int getCurrentBufferSizeSamples() override { return actualBufferSize; }\r
double getCurrentSampleRate() override { return 44100.0; }\r
- int getCurrentBitDepth() override { return 24; }\r
+ int getCurrentBitDepth() override { return 16; }\r
BigInteger getActiveOutputChannels() const override { BigInteger b; b.setRange (0, actualNumberOfOutputs, true); return b; }\r
BigInteger getActiveInputChannels() const override { BigInteger b; b.setRange (0, actualNumberOfInputs, true); return b; }\r
int getOutputLatencyInSamples() override { /* TODO */ return 0; }\r
static const char* const belaTypeName;\r
\r
private:\r
+\r
//==============================================================================\r
bool setup (BelaContext& context)\r
{\r
actualBufferSize = context.audioFrames;\r
- actualNumberOfInputs = context.audioInChannels;\r
- actualNumberOfOutputs = context.audioOutChannels;\r
+ actualNumberOfInputs = context.audioInChannels + context.analogInChannels;\r
+ actualNumberOfOutputs = context.audioOutChannels + context.analogOutChannels;\r
isBelaOpen = true;\r
firstCallback = true;\r
\r
if (callback != nullptr)\r
{\r
jassert (context.audioFrames <= actualBufferSize);\r
- auto numSamples = jmin (context.audioFrames, actualBufferSize);\r
- auto interleaved = ((context.flags & BELA_FLAG_INTERLEAVED) != 0);\r
- auto numIns = jmin (actualNumberOfInputs, (int) context.audioInChannels);\r
- auto numOuts = jmin (actualNumberOfOutputs, (int) context.audioOutChannels);\r
-\r
- int ch;\r
-\r
- if (interleaved && context.audioInChannels > 1)\r
- {\r
- for (ch = 0; ch < numIns; ++ch)\r
- {\r
- using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>;\r
- using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::Const>;\r
+ jassert ((context.flags & BELA_FLAG_INTERLEAVED) == 0);\r
\r
- channelInBuffer[ch] = audioInBuffer.getWritePointer (ch);\r
- DstSampleType dstData (audioInBuffer.getWritePointer (ch));\r
- SrcSampleType srcData (context.audioIn + ch, context.audioInChannels);\r
- dstData.convertSamples (srcData, numSamples);\r
- }\r
- }\r
- else\r
+ // Setup channelInBuffers\r
+ for (int ch = 0; ch < actualNumberOfInputs; ++ch)\r
{\r
- for (ch = 0; ch < numIns; ++ch)\r
- channelInBuffer[ch] = context.audioIn + (ch * numSamples);\r
+ if (ch < analogChannelStart)\r
+ channelInBuffer[ch] = &context.audioIn[ch * context.audioFrames];\r
+ else\r
+ channelInBuffer[ch] = &context.analogIn[(ch - analogChannelStart) * context.analogFrames];\r
}\r
\r
- for (; ch < actualNumberOfInputs; ++ch)\r
+ // Setup channelOutBuffers\r
+ for (int ch = 0; ch < actualNumberOfOutputs; ++ch)\r
{\r
- channelInBuffer[ch] = audioInBuffer.getWritePointer(ch);\r
- zeromem (audioInBuffer.getWritePointer (ch), sizeof (float) * numSamples);\r
+ if (ch < analogChannelStart)\r
+ channelOutBuffer[ch] = &context.audioOut[ch * context.audioFrames];\r
+ else\r
+ channelOutBuffer[ch] = &context.analogOut[(ch - analogChannelStart) * context.audioFrames];\r
}\r
\r
- for (int i = 0; i < actualNumberOfOutputs; ++i)\r
- channelOutBuffer[i] = ((interleaved && context.audioOutChannels > 1) || i >= context.audioOutChannels ? audioOutBuffer.getWritePointer (i)\r
- : context.audioOut + (i * numSamples));\r
-\r
callback->audioDeviceIOCallback (channelInBuffer.getData(), actualNumberOfInputs,\r
channelOutBuffer.getData(), actualNumberOfOutputs,\r
- numSamples);\r
-\r
- if (interleaved && context.audioOutChannels > 1)\r
- {\r
- for (int i = 0; i < numOuts; ++i)\r
- {\r
- using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::NonConst>;\r
- using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>;\r
-\r
- SrcSampleType srcData (channelOutBuffer[i]);\r
- DstSampleType dstData (context.audioOut + i, context.audioOutChannels);\r
-\r
- dstData.convertSamples (srcData, numSamples);\r
- }\r
- }\r
+ context.audioFrames);\r
}\r
}\r
\r
callback->audioDeviceStopped();\r
}\r
\r
+ const int analogChannelStart = 2;\r
\r
//==============================================================================\r
uint64_t expectedElapsedAudioSamples = 0;\r
uint32_t actualBufferSize = 0;\r
int actualNumberOfInputs = 0, actualNumberOfOutputs = 0;\r
\r
- AudioBuffer<float> audioInBuffer, audioOutBuffer;\r
HeapBlock<const float*> channelInBuffer;\r
HeapBlock<float*> channelOutBuffer;\r
\r
+ bool includeAnalogSupport;\r
+\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODevice)\r
};\r
\r
{\r
BelaAudioIODeviceType() : AudioIODeviceType ("Bela") {}\r
\r
- // TODO: support analog outputs\r
StringArray getDeviceNames (bool) const override { return StringArray (BelaAudioIODevice::belaTypeName); }\r
void scanForDevices() override {}\r
int getDefaultDeviceIndex (bool) const override { return 0; }\r
\r
AudioIODevice* createDevice (const String& outputName, const String& inputName) override\r
{\r
+ // TODO: switching whether to support analog/digital with possible multiple Bela device types?\r
if (outputName == BelaAudioIODevice::belaTypeName || inputName == BelaAudioIODevice::belaTypeName)\r
return new BelaAudioIODevice();\r
\r
SInt32 objectID = 0;\r
\r
if (CHECK_ERROR (MIDIObjectGetIntegerProperty (entity, kMIDIPropertyUniqueID, &objectID)))\r
+ {\r
info.identifier = String (objectID);\r
+ }\r
+ else\r
+ {\r
+ ScopedCFString str;\r
+\r
+ if (CHECK_ERROR (MIDIObjectGetStringProperty (entity, kMIDIPropertyUniqueID, &str.cfString)))\r
+ info.identifier = String::fromCFString (str.cfString);\r
+ }\r
\r
return info;\r
}\r
\r
if (! hasEnabledNetworkSession)\r
{\r
- MIDINetworkSession* session = [MIDINetworkSession defaultSession];\r
- session.enabled = YES;\r
- session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone;\r
+ auto iOSVersion = nsStringToJuce ([[UIDevice currentDevice] systemVersion]);\r
+ auto majorVersion = StringArray::fromTokens (iOSVersion, ".", {})[0].getIntValue();\r
+\r
+ if (majorVersion == 13)\r
+ {\r
+ // From the Xcode 11 release notes known issues:\r
+ // Attempting to create an MIDINetworkSession in a simulated device running\r
+ // iOS 13 won’t succeed. (54484923)\r
+ jassertfalse;\r
+ }\r
+ else\r
+ {\r
+ MIDINetworkSession* session = [MIDINetworkSession defaultSession];\r
+ session.enabled = YES;\r
+ session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone;\r
+ }\r
\r
hasEnabledNetworkSession = true;\r
}\r
static Array<MIDIEndpointRef> getEndpoints (bool isInput)\r
{\r
Array<MIDIEndpointRef> endpoints;\r
- auto numDevices = (isInput ? MIDIGetNumberOfSources() : MIDIGetNumberOfDevices());\r
+ auto numDevices = (isInput ? MIDIGetNumberOfSources() : MIDIGetNumberOfDestinations());\r
\r
for (ItemCount i = 0; i < numDevices; ++i)\r
endpoints.add (isInput ? MIDIGetSource (i) : MIDIGetDestination (i));\r
if (status != noErr)\r
return false;\r
\r
+ if (numFramesToRead == 0)\r
+ break;\r
+\r
if ((int) numFramesToRead < numThisTime)\r
{\r
numThisTime = (int) numFramesToRead;\r
\r
ID: juce_audio_formats\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE audio file format codecs\r
description: Classes for reading and writing various audio file formats.\r
website: http://www.juce.com/juce\r
: juceParameters.getParamID (audioProcessor, parameterIndex);\r
\r
aaxParamIDs.add (paramID);\r
- auto aaxParamID = aaxParamIDs.getReference (parameterIndex++).getCharPointer();\r
+ auto* aaxParamID = aaxParamIDs.getReference (parameterIndex++).toRawUTF8();\r
\r
paramMap.set (AAXClasses::getAAXParamHash (aaxParamID), juceParam);\r
\r
inline AAX_CParamID getAAXParamIDFromJuceIndex (int index) const noexcept\r
{\r
if (isPositiveAndBelow (index, aaxParamIDs.size()))\r
- return aaxParamIDs.getReference (index).getCharPointer();\r
+ return aaxParamIDs.getReference (index).toRawUTF8();\r
\r
return nullptr;\r
}\r
@tags{Audio}\r
*/\r
class StandalonePluginHolder : private AudioIODeviceCallback,\r
- private Timer\r
+ private Timer,\r
+ private Value::Listener\r
{\r
public:\r
//==============================================================================\r
\r
: settings (settingsToUse, takeOwnershipOfSettings),\r
channelConfiguration (channels),\r
- shouldMuteInput (! isInterAppAudioConnected()),\r
autoOpenMidiDevices (shouldAutoOpenMidiDevices)\r
{\r
+ shouldMuteInput.addListener (this);\r
+ shouldMuteInput = ! isInterAppAudioConnected();\r
+\r
createPlugin();\r
\r
auto inChannels = (channelConfiguration.size() > 0 ? channelConfiguration[0].numIns\r
//==============================================================================\r
Value& getMuteInputValue() { return shouldMuteInput; }\r
bool getProcessorHasPotentialFeedbackLoop() const { return processorHasPotentialFeedbackLoop; }\r
+ void valueChanged (Value& value) override { muteInput = (bool) value.getValue(); }\r
\r
//==============================================================================\r
File getLastFile() const\r
\r
// avoid feedback loop by default\r
bool processorHasPotentialFeedbackLoop = true;\r
+ std::atomic<bool> muteInput { true };\r
Value shouldMuteInput;\r
AudioBuffer<float> emptyBuffer;\r
bool autoOpenMidiDevices;\r
int numOutputChannels,\r
int numSamples) override\r
{\r
- const bool inputMuted = shouldMuteInput.getValue();\r
-\r
- if (inputMuted)\r
+ if (muteInput)\r
{\r
emptyBuffer.clear();\r
inputChannelData = emptyBuffer.getArrayOfReadPointers();\r
deleteEditor (true);\r
}\r
\r
- if (chunkMemoryTime > 0\r
- && chunkMemoryTime < juce::Time::getApproximateMillisecondCounter() - 2000\r
- && ! recursionCheck)\r
{\r
- chunkMemory.reset();\r
- chunkMemoryTime = 0;\r
+ ScopedLock lock (stateInformationLock);\r
+\r
+ if (chunkMemoryTime > 0\r
+ && chunkMemoryTime < juce::Time::getApproximateMillisecondCounter() - 2000\r
+ && ! recursionCheck)\r
+ {\r
+ chunkMemory.reset();\r
+ chunkMemoryTime = 0;\r
+ }\r
}\r
\r
if (editorComp != nullptr)\r
editorComp->checkVisibility();\r
}\r
\r
+ void setHasEditorFlag (bool shouldSetHasEditor)\r
+ {\r
+ auto hasEditor = (vstEffect.flags & Vst2::effFlagsHasEditor) != 0;\r
+\r
+ if (shouldSetHasEditor == hasEditor)\r
+ return;\r
+\r
+ if (shouldSetHasEditor)\r
+ vstEffect.flags |= Vst2::effFlagsHasEditor;\r
+ else\r
+ vstEffect.flags &= ~Vst2::effFlagsHasEditor;\r
+ }\r
+\r
void createEditorComp()\r
{\r
if (hasShutdown || processor == nullptr)\r
{\r
if (auto* ed = processor->createEditorIfNeeded())\r
{\r
- vstEffect.flags |= Vst2::effFlagsHasEditor;\r
+ setHasEditorFlag (true);\r
editorComp.reset (new EditorCompWrapper (*this, *ed));\r
}\r
else\r
{\r
- vstEffect.flags &= ~Vst2::effFlagsHasEditor;\r
+ setHasEditorFlag (false);\r
}\r
}\r
\r
pointer_sized_int handleOpen (VstOpCodeArguments)\r
{\r
// Note: most hosts call this on the UI thread, but wavelab doesn't, so be careful in here.\r
- if (processor->hasEditor())\r
- vstEffect.flags |= Vst2::effFlagsHasEditor;\r
- else\r
- vstEffect.flags &= ~Vst2::effFlagsHasEditor;\r
+ setHasEditorFlag (processor->hasEditor());\r
\r
return 0;\r
}\r
auto data = (void**) args.ptr;\r
bool onlyStoreCurrentProgramData = (args.index != 0);\r
\r
+ ScopedLock lock (stateInformationLock);\r
chunkMemory.reset();\r
+\r
if (onlyStoreCurrentProgramData)\r
processor->getCurrentProgramStateInformation (chunkMemory);\r
else\r
int32 byteSize = (int32) args.value;\r
bool onlyRestoreCurrentProgramData = (args.index != 0);\r
\r
- chunkMemory.reset();\r
- chunkMemoryTime = 0;\r
-\r
- if (byteSize > 0 && data != nullptr)\r
{\r
- if (onlyRestoreCurrentProgramData)\r
- processor->setCurrentProgramStateInformation (data, byteSize);\r
- else\r
- processor->setStateInformation (data, byteSize);\r
+ ScopedLock lock (stateInformationLock);\r
+\r
+ chunkMemory.reset();\r
+ chunkMemoryTime = 0;\r
+\r
+ if (byteSize > 0 && data != nullptr)\r
+ {\r
+ if (onlyRestoreCurrentProgramData)\r
+ processor->setCurrentProgramStateInformation (data, byteSize);\r
+ else\r
+ processor->setStateInformation (data, byteSize);\r
+ }\r
}\r
}\r
\r
double sampleRate = 44100.0;\r
int32 blockSize = 1024;\r
Vst2::AEffect vstEffect;\r
+ CriticalSection stateInformationLock;\r
juce::MemoryBlock chunkMemory;\r
- juce::uint32 chunkMemoryTime = 0;\r
+ uint32 chunkMemoryTime = 0;\r
std::unique_ptr<EditorCompWrapper> editorComp;\r
Vst2::ERect editorBounds;\r
MidiBuffer midiEvents;\r
}\r
\r
//==============================================================================\r
- Atomic<int> refCount;\r
+ std::atomic<int> refCount { 0 };\r
std::unique_ptr<AudioProcessor> audioProcessor;\r
\r
//==============================================================================\r
// Only update the AudioProcessor here if we're not playing,\r
// otherwise we get parallel streams of parameter value updates\r
// during playback\r
- if (owner.vst3IsPlaying.get() == 0)\r
+ if (! owner.vst3IsPlaying)\r
{\r
auto value = static_cast<float> (v);\r
\r
/ static_cast<Vst::ParamValue> (pluginInstance->getNumPrograms() - 1));\r
}\r
\r
- if (componentHandler != nullptr)\r
+ if (componentHandler != nullptr && ! inSetupProcessing)\r
componentHandler->restartComponent (Vst::kLatencyChanged | Vst::kParamValuesChanged);\r
}\r
\r
Vst::ParamID midiControllerToParameter[numMIDIChannels][Vst::kCountCtrlNumber];\r
\r
//==============================================================================\r
- Atomic<int> vst3IsPlaying { 0 };\r
+ std::atomic<bool> vst3IsPlaying { false },\r
+ inSetupProcessing { false };\r
+\r
float lastScaleFactorReceived = 1.0f;\r
\r
void setupParameters()\r
{\r
if (auto* constrainer = editor->getConstrainer())\r
{\r
- auto minW = (double) constrainer->getMinimumWidth();\r
- auto maxW = (double) constrainer->getMaximumWidth();\r
- auto minH = (double) constrainer->getMinimumHeight();\r
- auto maxH = (double) constrainer->getMaximumHeight();\r
+ auto scale = editor->getTransform().getScaleFactor();\r
+\r
+ auto minW = (double) (constrainer->getMinimumWidth() * scale);\r
+ auto maxW = (double) (constrainer->getMaximumWidth() * scale);\r
+ auto minH = (double) (constrainer->getMinimumHeight() * scale);\r
+ auto maxH = (double) (constrainer->getMaximumHeight() * scale);\r
\r
auto width = (double) (rectToCheck->right - rectToCheck->left);\r
auto height = (double) (rectToCheck->bottom - rectToCheck->top);\r
#if JUCE_MAC\r
if (host.isWavelab() || host.isReaper())\r
#else\r
- if (host.isWavelab())\r
+ if (host.isWavelab() || host.isAbletonLive())\r
#endif\r
setBounds (0, 0, w, h);\r
}\r
~JuceVST3Component() override\r
{\r
if (juceVST3EditController != nullptr)\r
- juceVST3EditController->vst3IsPlaying = 0;\r
+ juceVST3EditController->vst3IsPlaying = false;\r
\r
if (pluginInstance != nullptr)\r
if (pluginInstance->getPlayHead() == this)\r
tresult PLUGIN_API disconnect (IConnectionPoint*) override\r
{\r
if (juceVST3EditController != nullptr)\r
- juceVST3EditController->vst3IsPlaying = 0;\r
+ juceVST3EditController->vst3IsPlaying = false;\r
\r
juceVST3EditController = nullptr;\r
return kResultTrue;\r
\r
tresult PLUGIN_API setupProcessing (Vst::ProcessSetup& newSetup) override\r
{\r
+ ScopedInSetupProcessingSetter inSetupProcessingSetter (juceVST3EditController);\r
+\r
if (canProcessSampleSize (newSetup.symbolicSampleSize) != kResultTrue)\r
return kResultFalse;\r
\r
processContext = *data.processContext;\r
\r
if (juceVST3EditController != nullptr)\r
- juceVST3EditController->vst3IsPlaying = processContext.state & Vst::ProcessContext::kPlaying;\r
+ juceVST3EditController->vst3IsPlaying = (processContext.state & Vst::ProcessContext::kPlaying) != 0;\r
}\r
else\r
{\r
zerostruct (processContext);\r
\r
if (juceVST3EditController != nullptr)\r
- juceVST3EditController->vst3IsPlaying = 0;\r
+ juceVST3EditController->vst3IsPlaying = false;\r
}\r
\r
midiBuffer.clear();\r
}\r
\r
private:\r
+ //==============================================================================\r
+ struct ScopedInSetupProcessingSetter\r
+ {\r
+ ScopedInSetupProcessingSetter (JuceVST3EditController* c)\r
+ : controller (c)\r
+ {\r
+ if (controller != nullptr)\r
+ controller->inSetupProcessing = true;\r
+ }\r
+\r
+ ~ScopedInSetupProcessingSetter()\r
+ {\r
+ if (controller != nullptr)\r
+ controller->inSetupProcessing = false;\r
+ }\r
+\r
+ private:\r
+ JuceVST3EditController* controller = nullptr;\r
+ };\r
+\r
//==============================================================================\r
template <typename FloatType>\r
void processAudio (Vst::ProcessData& data, Array<FloatType*>& channelList)\r
//==============================================================================\r
ScopedJuceInitialiser_GUI libraryInitialiser;\r
\r
- Atomic<int> refCount { 1 };\r
+ std::atomic<int> refCount { 1 };\r
\r
AudioProcessor* pluginInstance;\r
ComSmartPtr<Vst::IHostApplication> host;\r
\r
private:\r
//==============================================================================\r
- Atomic<int> refCount { 1 };\r
+ std::atomic<int> refCount { 1 };\r
const PFactoryInfo factoryInfo;\r
ComSmartPtr<Vst::IHostApplication> host;\r
\r
\r
ID: juce_audio_plugin_client\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE audio plugin wrapper classes\r
description: Classes for building VST, VST3, AudioUnit, AAX and RTAS plugins.\r
website: http://www.juce.com/juce\r
if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets,\r
kAudioUnitScope_Global, 0, &presets, &sz) == noErr)\r
{\r
- num = (int) CFArrayGetCount (presets);\r
- CFRelease (presets);\r
+ if (presets != nullptr)\r
+ {\r
+ num = (int) CFArrayGetCount (presets);\r
+ CFRelease (presets);\r
+ }\r
}\r
\r
return num;\r
AudioPlayHead::CurrentPositionInfo position;\r
playHead->getCurrentPosition (position);\r
\r
- context.projectTimeSamples = position.timeInSamples; //Must always be valid, as stated by the VST3 SDK\r
- context.projectTimeMusic = position.timeInSeconds; //Does not always need to be valid...\r
+ context.projectTimeSamples = position.timeInSamples; // Must always be valid, as stated by the VST3 SDK\r
+ context.projectTimeMusic = position.ppqPosition; // Does not always need to be valid...\r
context.tempo = position.bpm;\r
context.timeSigNumerator = position.timeSigNumerator;\r
context.timeSigDenominator = position.timeSigDenominator;\r
\r
Vst2::ERect* rect = nullptr;\r
dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0);\r
- setSize (rect->right - rect->left, rect->bottom - rect->top);\r
+\r
+ if (rect != nullptr)\r
+ setSize (rect->right - rect->left, rect->bottom - rect->top);\r
+ else\r
+ setSize (1, 1);\r
\r
setOpaque (true);\r
setVisible (true);\r
\r
ID: juce_audio_processors\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE audio processor classes\r
description: Classes for loading and playing VST, AU, LADSPA, or internally-generated audio processors.\r
website: http://www.juce.com/juce\r
/** Returns the group of parameters managed by this AudioProcessor. */\r
const AudioProcessorParameterGroup& getParameterTree() const;\r
\r
- /** Returns the group of parameters managed by this AudioProcessor. */\r
+ /** Sets the group of parameters managed by this AudioProcessor. */\r
void setParameterTree (AudioProcessorParameterGroup&& newTree);\r
\r
/** A processor should implement this method so that the host can ask it to\r
struct JUCE_API Connection\r
{\r
//==============================================================================\r
+ Connection() = default;\r
Connection (NodeAndChannel source, NodeAndChannel destination) noexcept;\r
\r
Connection (const Connection&) = default;\r
\r
//==============================================================================\r
/** The channel and node which is the input source for this connection. */\r
- NodeAndChannel source;\r
+ NodeAndChannel source { {}, 0 };\r
\r
/** The channel and node which is the input source for this connection. */\r
- NodeAndChannel destination;\r
+ NodeAndChannel destination { {}, 0 };\r
};\r
\r
//==============================================================================\r
*/\r
AudioProcessorParameterWithID (const String& parameterID,\r
const String& parameterName,\r
- const String& parameterLabel = String(),\r
+ const String& parameterLabel = {},\r
Category parameterCategory = AudioProcessorParameter::genericParameter);\r
\r
/** Destructor. */\r
/** Provides access to the parameter's category. */\r
const Category category;\r
\r
-private:\r
String getName (int) const override;\r
String getLabel() const override;\r
Category getCategory() const override;\r
\r
+private:\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameterWithID)\r
};\r
\r
return;\r
\r
lastValue = newValue;\r
- sendValueChangedMessageToListeners (newValue);\r
+\r
+ if (onValueChanged != nullptr)\r
+ onValueChanged();\r
}\r
\r
//==============================================================================\r
unnormalisedValue (getRange().convertFrom0to1 (parameter.getDefaultValue()))\r
{\r
parameter.addListener (this);\r
+\r
+ if (auto* ptr = dynamic_cast<Parameter*> (¶meter))\r
+ ptr->onValueChanged = [this] { parameterValueChanged ({}, {}); };\r
}\r
\r
~ParameterAdapter() override { parameter.removeListener (this); }\r
UndoManager* const undoManager;\r
\r
//==============================================================================\r
+private:\r
+ class ParameterAdapter;\r
+\r
+public:\r
/** A parameter class that maintains backwards compatibility with deprecated\r
AudioProcessorValueTreeState functionality.\r
\r
private:\r
void valueChanged (float) override;\r
\r
+ std::function<void()> onValueChanged;\r
+\r
const float unsnappedDefault;\r
const bool metaParameter, automatable, discrete, boolean;\r
- float lastValue = 0.0f;\r
+ float lastValue = -1.0f;\r
+\r
+ friend class AudioProcessorValueTreeState::ParameterAdapter;\r
};\r
\r
//==============================================================================\r
bool, bool, bool, AudioProcessorParameter::Category, bool));\r
\r
//==============================================================================\r
- class ParameterAdapter;\r
-\r
#if JUCE_UNIT_TESTS\r
friend struct ParameterAdapterTests;\r
#endif\r
AudioDeviceManager& deviceManager;\r
\r
private:\r
- //=============================================================================\r
+ //==============================================================================\r
AudioDeviceManager defaultDeviceManager;\r
AudioSourcePlayer audioSourcePlayer;\r
bool usingCustomDeviceManager;\r
\r
ID: juce_audio_utils\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE extra audio utility classes\r
description: Classes for audio-related GUI and miscellaneous tasks.\r
website: http://www.juce.com/juce\r
setBounds (bounds);\r
\r
toFront (true);\r
- setOpaque (! bounds.isEmpty());\r
+ setOpaque (true);\r
\r
controller = [[CABTMIDICentralViewController alloc] init];\r
nativeSelectorComponent.setView ([controller view]);\r
/** Metadata for a given config item */\r
struct ConfigMetaData\r
{\r
- static constexpr int32 numOptionNames = 8;\r
+ static constexpr int32 numOptionNames = 16;\r
\r
enum class ConfigType\r
{\r
void setDeviceIndex (TopologyIndex newDeviceIndex) { deviceIndex = newDeviceIndex; }\r
void setDeviceComms (PhysicalTopologySource::DeviceConnection* newConn) { deviceConnection = newConn; }\r
\r
- static constexpr uint32 numConfigItems = 64;\r
+ static constexpr uint32 numConfigItems = 69;\r
\r
/** Structure describing a configuration */\r
struct ConfigDescription\r
{ mode, 4, 1, 5, false, "Mode", ConfigType::integer, {}, "Play mode" },\r
{ volume, 100, 0, 127, false, "Volume", ConfigType::integer, {}, "Play mode" },\r
{ scale, 0, 0, 18, false, "Scale", ConfigType::integer, {}, "Play mode" }, // NOTE: Should be options\r
+ { key, 0, 0, 11, false, "Key", ConfigType::options, { "C", "C#", "D", "D#",\r
+ "E", "F", "F#", "G",\r
+ "G#", "A", "A#", "B"}, "Play mode" },\r
{ hideMode, 0, 0, 1, false, "Hide Mode", ConfigType::boolean, {}, "Play mode" },\r
{ chord, 0, 0, 127, false, "Chord", ConfigType::integer, {}, "Play mode" }, // NOTE: Should be options\r
{ arpPattern, 0, 0, 127, false, "Arp Pattern", ConfigType::integer, {}, "Play mode" },\r
{ tempo, 120, 1, 300, false, "Tempo", ConfigType::integer, {}, "Rhythm" },\r
+ { key, 0, 0, 11, false, "Key", ConfigType::options, { "C", "C#", "D", "D#",\r
+ "E", "F", "F#", "G",\r
+ "G#", "A", "A#", "B"}, "Play mode" },\r
+ { autoTransposeToKey, 0, 0, 1, false, "Auto Transpose To Key",ConfigType::boolean, {}, "Pitch" },\r
{ xTrackingMode, 1, 1, 4, false, "Glide Tracking Mode", ConfigType::options, { "Multi-Channel",\r
"Last Played",\r
"Highest",\r
"Hardest" }, "Play mode" },\r
\r
{ gammaCorrection, 0, 0, 1, false, "Gamma Correction", ConfigType::boolean, {}, {} },\r
+ { globalKeyColour, INT32_MIN, INT32_MIN, INT32_MAX, false, "Global Key Colour", ConfigType::colour, {}, "Colour" },\r
+ { rootKeyColour, INT32_MIN, INT32_MIN, INT32_MAX, false, "Root Key Colour" , ConfigType::colour, {}, "Colour" },\r
+ { brightness, 100, 0, 100, false, "Brightness", ConfigType::integer, {}, "Colour" },\r
\r
// These can be defined for unique usage for a given Littlefoot script\r
{ user0, 0, 0, 127, false, {}, ConfigType::integer, {}, {} },\r
void clear() noexcept { touches.clear(); }\r
\r
private:\r
- //==========================================================================\r
+ //==============================================================================\r
static bool matches (const TouchSurface::Touch& t1,\r
const TouchSurface::Touch& t2) noexcept\r
{\r
\r
ID: juce_blocks_basics\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: Provides low-level control over ROLI BLOCKS devices\r
description: JUCE wrapper for low-level control over ROLI BLOCKS devices.\r
website: http://developer.roli.com\r
\r
==============================================================================\r
*/\r
+#ifndef JUCE_DUMP_LITTLEFOOT_HEAP_STATUS\r
+ #define JUCE_DUMP_LITTLEFOOT_HEAP_STATUS 0\r
+#endif\r
\r
-#define JUCE_DUMP_LITTLEFOOT_HEAP_STATUS 0\r
+#if JUCE_DUMP_LITTLEFOOT_HEAP_STATUS\r
+ #define JUCE_LOG_LITTLEFOOT_HEAP(text) DBG(text)\r
+#else\r
+ #define JUCE_LOG_LITTLEFOOT_HEAP(text)\r
+#endif\r
\r
namespace littlefoot\r
{\r
resetDeviceStateToUnknown();\r
}\r
\r
- void clear() noexcept\r
+ void reset()\r
{\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("Resetting heap state");\r
+ clearTargetData();\r
+ resetDeviceStateToUnknown();\r
+ lastPacketIndexReceived = 0;\r
+ }\r
+\r
+ void clearTargetData() noexcept\r
+ {\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("Clearing target heap data");\r
zeromem (targetData, sizeof (targetData));\r
- invalidateData();\r
+ needsSyncing = true;\r
+ programStateKnown = false;\r
}\r
\r
void resetDeviceStateToUnknown()\r
{\r
- invalidateData();\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("Resetting device state to unknown");\r
+ needsSyncing = true;\r
+ programStateKnown = false;\r
messagesSent.clear();\r
resetDataRangeToUnknown (0, ImplementationClass::maxBlockSize);\r
}\r
\r
void setByte (size_t offset, uint8 value) noexcept\r
{\r
- if (offset < blockSize)\r
+ if (offset >= blockSize)\r
{\r
- if (targetData[offset] != value)\r
- {\r
- targetData[offset] = value;\r
- needsSyncing = true;\r
-\r
- if (programStateKnown && offset < programSize)\r
- programStateKnown = false;\r
- }\r
+ jassertfalse;\r
+ return;\r
}\r
- else\r
+\r
+ if (targetData[offset] != value)\r
{\r
- jassertfalse;\r
+ targetData[offset] = value;\r
+ needsSyncing = true;\r
+\r
+ if (offset < programSize)\r
+ programStateKnown = false;\r
}\r
}\r
\r
\r
if (readLittleEndianBitsInBuffer (targetData, startBit, numBits) != value)\r
{\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("Set bits sync " << String (startBit) << " " << String (numBits) << String (value));\r
+\r
writeLittleEndianBitsInBuffer (targetData, startBit, numBits, value);\r
- invalidateData();\r
+\r
+ needsSyncing = true;\r
+\r
+ if (startBit < programSize)\r
+ programStateKnown = false;\r
}\r
}\r
\r
return 0;\r
}\r
\r
- void invalidateData() noexcept\r
- {\r
- needsSyncing = true;\r
- programStateKnown = false;\r
- }\r
-\r
bool isFullySynced() const noexcept\r
{\r
return ! needsSyncing;\r
\r
m->dispatchTime = Time::getCurrentTime();\r
bi.sendMessageToDevice (m->packet);\r
- //DBG ("Sending packet " << (int) m->packetIndex << " - " << m->packet.size() << " bytes, device " << bi.getDeviceIndex());\r
+\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("Sending packet " << (int) m->packetIndex << " - " << m->packet.size() << " bytes, device " << bi.getDeviceIndex());\r
\r
if (getTotalSizeOfMessagesSent() > 200)\r
break;\r
\r
void handleACKFromDevice (ImplementationClass& bi, uint32 packetIndex) noexcept\r
{\r
- //DBG ("ACK " << (int) packetIndex << " device " << (int) bi.getDeviceIndex());\r
+ if (packetIndex == lastPacketIndexReceived)\r
+ return;\r
\r
- if (lastPacketIndexReceived != packetIndex)\r
- {\r
- lastPacketIndexReceived = packetIndex;\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("ACK " << (int) packetIndex << " device " << (int) bi.getDeviceIndex()\r
+ << ", last packet received " << String (lastPacketIndexReceived));\r
\r
- for (int i = messagesSent.size(); --i >= 0;)\r
- {\r
- auto& m = *messagesSent.getUnchecked(i);\r
+ lastPacketIndexReceived = packetIndex;\r
\r
- if (m.packetIndex == packetIndex)\r
- {\r
- for (uint32 j = 0; j < blockSize; ++j)\r
- deviceState[j] = m.resultDataState[j];\r
+ for (int i = messagesSent.size(); --i >= 0;)\r
+ {\r
+ auto& m = *messagesSent.getUnchecked(i);\r
\r
- programStateKnown = false;\r
- messagesSent.removeRange (0, i + 1);\r
- dumpStatus();\r
- sendChanges (bi, false);\r
+ if (m.packetIndex == packetIndex)\r
+ {\r
+ for (uint32 j = 0; j < blockSize; ++j)\r
+ deviceState[j] = m.resultDataState[j];\r
\r
- if (messagesSent.isEmpty())\r
- needsSyncing = false;\r
+ programStateKnown = false;\r
+ messagesSent.removeRange (0, i + 1);\r
+ dumpStatus();\r
+ sendChanges (bi, false);\r
\r
- return;\r
+ if (messagesSent.isEmpty())\r
+ {\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("Heap fully synced");\r
+ needsSyncing = false;\r
}\r
- }\r
\r
- resetDeviceStateToUnknown();\r
+ return;\r
+ }\r
}\r
+\r
+ resetDeviceStateToUnknown();\r
}\r
\r
bool isProgramLoaded() noexcept\r
{\r
if (! programStateKnown)\r
{\r
- programStateKnown = true;\r
-\r
uint8 deviceMemory[ImplementationClass::maxBlockSize];\r
\r
for (size_t i = 0; i < blockSize; ++i)\r
littlefoot::Program prog (deviceMemory, (uint32) blockSize);\r
programLoaded = prog.checksumMatches();\r
programSize = prog.getProgramSize();\r
+\r
+ programStateKnown = true;\r
}\r
\r
return programLoaded;\r
\r
ignoreUnused (proportionOK);\r
\r
- DBG ("Heap: " << areas << " " << String (roundToInt (100 * proportionOK)) << "% "\r
- << (isProgramLoaded() ? "Ready" : "Loading"));\r
+ JUCE_LOG_LITTLEFOOT_HEAP ("Heap: " << areas << " " << String (roundToInt (100 * proportionOK))\r
+ << "% " << (isProgramLoaded() ? "Ready" : "Loading"));\r
#endif\r
}\r
\r
chord = 24,\r
arpPattern = 25,\r
tempo = 26,\r
+ key = 27,\r
+ autoTransposeToKey = 28,\r
// Tracking\r
xTrackingMode = 30,\r
yTrackingMode = 31,\r
zTrackingMode = 32,\r
// Graphics\r
gammaCorrection = 33,\r
+ globalKeyColour = 34,\r
+ rootKeyColour = 35,\r
+ brightness = 36,\r
// User\r
user0 = 64,\r
user1 = 65,\r
static constexpr uint8 maxConfigIndex = uint8 (ConfigItemId::user0) + numberOfUserConfigs;\r
\r
static constexpr uint8 configUserConfigNameLength = 32;\r
-static constexpr uint8 configMaxOptions = 8;\r
+static constexpr uint8 configMaxOptions = 16;\r
static constexpr uint8 configOptionNameLength = 16;\r
\r
//==============================================================================\r
"setButtonMinMaxDefault/viiii",\r
"setButtonColours/viii",\r
"setButtonTriState/vii",\r
+ "padControllerInitDefault/vb",\r
+ "padControllerReset/v",\r
+ "padControllerRegenDefault/v",\r
+ "padControllerRepaint/v",\r
+ "padControllerDrawPad/vi",\r
+ "setUseDefaultKeyHandler/vb",\r
+ "setUseDefaultKeyHandler/vbb",\r
+\r
nullptr\r
};\r
\r
if (connectionTime == Time())\r
connectionTime = Time::getCurrentTime();\r
\r
- versionNumber = deviceInfo.version.asString();\r
- name = deviceInfo.name.asString();\r
- isMaster = deviceInfo.isMaster;\r
- masterUID = deviceInfo.masterUid;\r
- batteryCharging = deviceInfo.batteryCharging;\r
- batteryLevel = deviceInfo.batteryLevel;\r
- topologyIndex = deviceInfo.index;\r
+ updateDeviceInfo (deviceInfo);\r
+\r
+ remoteHeap.reset();\r
\r
setProgram (nullptr);\r
- remoteHeap.resetDeviceStateToUnknown();\r
\r
if (auto surface = dynamic_cast<TouchSurfaceImplementation*> (touchSurface.get()))\r
surface->activateTouchSurface();\r
updateMidiConnectionListener();\r
}\r
\r
+ void updateDeviceInfo (const DeviceInfo& deviceInfo)\r
+ {\r
+ versionNumber = deviceInfo.version.asString();\r
+ name = deviceInfo.name.asString();\r
+ isMaster = deviceInfo.isMaster;\r
+ masterUID = deviceInfo.masterUid;\r
+ batteryCharging = deviceInfo.batteryCharging;\r
+ batteryLevel = deviceInfo.batteryLevel;\r
+ topologyIndex = deviceInfo.index;\r
+ }\r
+\r
void setToMaster (bool shouldBeMaster)\r
{\r
isMaster = shouldBeMaster;\r
\r
if (program == nullptr)\r
{\r
- remoteHeap.clear();\r
+ remoteHeap.clearTargetData();\r
return Result::ok();\r
}\r
\r
programSize = (uint32) size;\r
\r
remoteHeap.resetDataRangeToUnknown (0, remoteHeap.blockSize);\r
- remoteHeap.clear();\r
+ remoteHeap.clearTargetData();\r
remoteHeap.sendChanges (*this, true);\r
\r
remoteHeap.resetDataRangeToUnknown (0, (uint32) size);\r
\r
remoteHeap.sendChanges (*this, false);\r
\r
- if (lastMessageSendTime < Time::getCurrentTime() - RelativeTime::milliseconds (pingIntervalMs))\r
+ if (lastMessageSendTime < Time::getCurrentTime() - getPingInterval())\r
sendCommandMessage (BlocksProtocol::ping);\r
}\r
\r
+ RelativeTime getPingInterval()\r
+ {\r
+ return RelativeTime::milliseconds (isMaster ? masterPingIntervalMs : dnaPingIntervalMs);\r
+ }\r
+\r
//==============================================================================\r
int32 getLocalConfigValue (uint32 item) override\r
{\r
\r
MIDIDeviceConnection* listenerToMidiConnection = nullptr;\r
\r
- static constexpr int pingIntervalMs = 400;\r
+ static constexpr int masterPingIntervalMs = 400;\r
+ static constexpr int dnaPingIntervalMs = 1666;\r
\r
static constexpr uint32 maxBlockSize = BlocksProtocol::padBlockProgramAndHeapSize;\r
static constexpr uint32 maxPacketCounter = BlocksProtocol::PacketCounter::maxValue;\r
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2019 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ The code included in this file is provided under the terms of the ISC license\r
+ http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
+ To use, copy, modify, and/or distribute this software for any purpose with or\r
+ without fee is hereby granted provided that the above copyright notice and\r
+ this permission notice appear in all copies.\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+namespace juce\r
+{\r
+ class BlockSerialReader\r
+ : private MIDIDeviceConnection::Listener,\r
+ private Timer\r
+ {\r
+ public:\r
+ //==============================================================================\r
+ BlockSerialReader (MIDIDeviceConnection& deviceConnectionToUse) : deviceConnection (deviceConnectionToUse)\r
+ {\r
+ deviceConnection.addListener (this);\r
+ startTimer (10);\r
+ }\r
+\r
+ ~BlockSerialReader() override\r
+ {\r
+ deviceConnection.removeListener (this);\r
+ }\r
+\r
+ bool hasSerial() const { return serial.isNotEmpty(); }\r
+\r
+ String getSerial() const { return serial; }\r
+\r
+ private:\r
+ MIDIDeviceConnection& deviceConnection;\r
+ String serial;\r
+\r
+ bool shouldStop() { return hasSerial(); }\r
+\r
+ //==============================================================================\r
+ void timerCallback() override\r
+ {\r
+ if (shouldStop())\r
+ {\r
+ stopTimer();\r
+ return;\r
+ }\r
+\r
+ sendRequest();\r
+ startTimer (300);\r
+ }\r
+\r
+ void sendRequest()\r
+ {\r
+ const uint8 dumpRequest[] = { 0xf0, 0x00, 0x21, 0x10, 0x78, 0x3f, 0xf7 };\r
+ deviceConnection.sendMessageToDevice (dumpRequest, sizeof (dumpRequest));\r
+ }\r
+\r
+ void handleIncomingMidiMessage (const MidiMessage& message) override\r
+ {\r
+ if (hasSerial())\r
+ return;\r
+\r
+ if (isResponse (message))\r
+ parseResponse (message);\r
+ }\r
+\r
+ void connectionBeingDeleted (const MIDIDeviceConnection&) override\r
+ {\r
+ stopTimer();\r
+ }\r
+\r
+ bool isResponse (const MidiMessage message)\r
+ {\r
+ const uint8 roliDumpHeader[] = { 0xf0, 0x00, 0x21, 0x10, 0x78};\r
+ return memcmp (message.getRawData(), roliDumpHeader, sizeof (roliDumpHeader)) == 0;\r
+ }\r
+\r
+ void parseResponse (const MidiMessage& message)\r
+ {\r
+ int index = findMacAddressStart (message);\r
+\r
+ if (index >= 0)\r
+ {\r
+ const int macSize = 17;\r
+ const int offset = index + macSize;\r
+ const int serialSize = 16;\r
+\r
+ if (message.getRawDataSize() - offset < serialSize)\r
+ {\r
+ jassertfalse;\r
+ return;\r
+ }\r
+\r
+ serial = String ((const char*)message.getRawData() + offset, serialSize);\r
+ }\r
+ }\r
+\r
+ int findMacAddressStart (const MidiMessage& message)\r
+ {\r
+ const uint8 macStart[] = { '4', '8', ':', 'B', '6', ':', '2', '0', ':' };\r
+ return findSequence (macStart, sizeof (macStart), message);\r
+ }\r
+\r
+ int findSequence (const uint8* sequence, int sequenceSize, const MidiMessage& message)\r
+ {\r
+ for (int i = 0; i < message.getRawDataSize() - sequenceSize; i++)\r
+ {\r
+ if (memcmp (message.getRawData() + i, sequence, size_t (sequenceSize)) == 0)\r
+ return i;\r
+ }\r
+\r
+ return -1;\r
+ }\r
+\r
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlockSerialReader)\r
+ };\r
+}\r
setMidiMessageCallback();\r
}\r
\r
+ initialiseSerialReader();\r
+\r
startTimer (200);\r
sendTopologyRequest();\r
}\r
Array<MemoryBlock> incomingPackets;\r
\r
std::unique_ptr<DepreciatedVersionReader> depreciatedVersionReader;\r
+ std::unique_ptr<BlockSerialReader> masterSerialReader;\r
\r
struct TouchStart { float x, y; };\r
TouchList<TouchStart> touchStartPositions;\r
\r
static constexpr Block::UID invalidUid = 0;\r
- Block::UID masterBlock = invalidUid;\r
+ Block::UID masterBlockUid = invalidUid;\r
\r
//==============================================================================\r
void timerCallback() override\r
\r
checkApiTimeouts (now);\r
startApiModeOnConnectedBlocks();\r
- requestMasterBlockVersionIfNeeded();\r
+ checkMasterBlockVersion();\r
+ checkMasterSerial();\r
}\r
\r
//==============================================================================\r
}\r
\r
//==============================================================================\r
- void requestMasterBlockVersionIfNeeded()\r
+ void checkMasterBlockVersion()\r
{\r
if (depreciatedVersionReader == nullptr)\r
return;\r
\r
if (masterVersion.isNotEmpty())\r
{\r
- const auto masterIndex = getIndexFromDeviceID (masterBlock);\r
+ const auto masterIndex = getIndexFromDeviceID (masterBlockUid);\r
\r
if (masterIndex >= 0)\r
setVersion (BlocksProtocol::TopologyIndex (masterIndex), masterVersion);\r
if (info->version == versionNumber)\r
return;\r
\r
- if (info->uid == masterBlock)\r
+ if (info->uid == masterBlockUid)\r
depreciatedVersionReader.reset();\r
\r
info->version = versionNumber;\r
}\r
}\r
\r
+ //==============================================================================\r
+ void checkMasterSerial()\r
+ {\r
+ if (masterSerialReader == nullptr)\r
+ initialiseSerialReader();\r
+\r
+ if (masterSerialReader == nullptr)\r
+ return;\r
+\r
+ if (masterBlockUid != invalidUid && masterSerialReader->hasSerial())\r
+ {\r
+ auto uid = getBlockUIDFromSerialNumber (masterSerialReader->getSerial());\r
+\r
+ if (uid != masterBlockUid)\r
+ updateMasterUid (uid);\r
+ }\r
+ }\r
+\r
+ void updateMasterUid (const Block::UID newMasterUid)\r
+ {\r
+ LOG_CONNECTIVITY ("Updating master from " + String (masterBlockUid) + " to " + String (newMasterUid));\r
+\r
+ masterBlockUid = newMasterUid;\r
+\r
+ Array<DeviceInfo> devicesToUpdate;\r
+\r
+ for (auto& info : currentDeviceInfo)\r
+ {\r
+ if (info.masterUid != masterBlockUid)\r
+ {\r
+ info.masterUid = masterBlockUid;\r
+\r
+ info.isMaster = info.uid == masterBlockUid;\r
+\r
+ devicesToUpdate.add (info);\r
+ }\r
+ }\r
+\r
+ detector.handleDevicesUpdated (devicesToUpdate);\r
+ }\r
+\r
+ Block::UID determineMasterBlockUid (Array<BlocksProtocol::DeviceStatus> devices)\r
+ {\r
+ if (masterSerialReader != nullptr && masterSerialReader->hasSerial())\r
+ {\r
+ auto foundSerial = masterSerialReader->getSerial();\r
+ for (const auto& device : incomingTopologyDevices)\r
+ {\r
+ if (device.serialNumber.asString() == foundSerial)\r
+ {\r
+ LOG_CONNECTIVITY ("Found master from serial " + foundSerial);\r
+ return getBlockUIDFromSerialNumber (foundSerial);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (devices.size() > 0)\r
+ {\r
+ LOG_CONNECTIVITY ("Found master from first device " + devices[0].serialNumber.asString());\r
+ return getBlockUIDFromSerialNumber (incomingTopologyDevices[0].serialNumber);\r
+ }\r
+\r
+ jassertfalse;\r
+ return invalidUid;\r
+ }\r
+\r
//==============================================================================\r
struct BlockPingTime\r
{\r
\r
void forceApiDisconnected (Block::UID uid)\r
{\r
- Array<Block::UID> toRemove;\r
-\r
for (auto dependentUID : detector.getDnaDependentDeviceUIDs (uid))\r
removeDevice (dependentUID);\r
\r
removeDevice (uid);\r
\r
- if (uid == masterBlock)\r
- masterBlock = invalidUid;\r
+ if (uid == masterBlockUid)\r
+ {\r
+ masterBlockUid = invalidUid;\r
+ masterSerialReader.reset();\r
+ }\r
\r
scheduleNewTopologyRequest();\r
}\r
for (const auto& uid : toRemove)\r
removeDevice (uid);\r
\r
+ if (masterBlockUid == invalidUid)\r
+ {\r
+ masterBlockUid = determineMasterBlockUid (incomingTopologyDevices);\r
+ initialiseVersionReader();\r
+ }\r
+\r
//Add new devices\r
for (const auto& device : incomingTopologyDevices)\r
{\r
const auto uid = getBlockUIDFromSerialNumber (device.serialNumber);\r
\r
- if (! getDeviceInfoFromUID (uid))\r
+ if (getDeviceInfoFromUID (uid) == nullptr)\r
{\r
- // For backwards compatibility we assume the first device we see in a group is the master and won't change\r
- if (masterBlock == invalidUid)\r
- {\r
- masterBlock = uid;\r
-\r
- if (auto midiDeviceConnection = static_cast<MIDIDeviceConnection*> (deviceConnection.get()))\r
- depreciatedVersionReader = std::make_unique<DepreciatedVersionReader> (*midiDeviceConnection);\r
- }\r
-\r
currentDeviceInfo.add ({ uid,\r
device.index,\r
device.serialNumber,\r
BlocksProtocol::BlockName(),\r
device.batteryLevel,\r
device.batteryCharging,\r
- masterBlock });\r
+ masterBlockUid });\r
}\r
}\r
}\r
detector.handleConnectionsChanged();\r
}\r
\r
+ void initialiseVersionReader()\r
+ {\r
+ if (auto midiDeviceConnection = static_cast<MIDIDeviceConnection*> (deviceConnection.get()))\r
+ depreciatedVersionReader = std::make_unique<DepreciatedVersionReader> (*midiDeviceConnection);\r
+ }\r
+\r
+ void initialiseSerialReader()\r
+ {\r
+ if (auto midiDeviceConnection = static_cast<MIDIDeviceConnection*> (deviceConnection.get()))\r
+ masterSerialReader = std::make_unique<BlockSerialReader> (*midiDeviceConnection);\r
+ }\r
+\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectedDeviceGroup)\r
};\r
\r
triggerAsyncUpdate();\r
}\r
\r
- void handleDeviceUpdated (const DeviceInfo& info)\r
+ void handleDevicesUpdated (const Array<DeviceInfo>& infos)\r
{\r
- if (containsBlockWithUID (blocksToRemove, info.uid))\r
- return;\r
+ bool shouldTriggerUpdate { false };\r
\r
- const auto blockIt = std::find_if (currentTopology.blocks.begin(), currentTopology.blocks.end(),\r
- [uid = info.uid] (Block::Ptr block) { return uid == block->uid; });\r
-\r
- if (blockIt != currentTopology.blocks.end())\r
+ for (auto& info : infos)\r
{\r
- const Block::Ptr block { *blockIt };\r
+ if (containsBlockWithUID (blocksToRemove, info.uid))\r
+ continue;\r
+\r
+ const auto blockIt = std::find_if (currentTopology.blocks.begin(), currentTopology.blocks.end(),\r
+ [uid = info.uid] (Block::Ptr block) { return uid == block->uid; });\r
\r
- if (auto blockImpl = BlockImpl::getFrom (block.get()))\r
- blockImpl->markReconnected (info);\r
\r
- if (! containsBlockWithUID (blocksToAdd, info.uid))\r
+ if (blockIt != currentTopology.blocks.end())\r
{\r
- blocksToUpdate.addIfNotAlreadyThere (block);\r
- triggerAsyncUpdate();\r
+ const Block::Ptr block { *blockIt };\r
+\r
+ if (auto blockImpl = BlockImpl::getFrom (block.get()))\r
+ blockImpl->updateDeviceInfo (info);\r
+\r
+ if (! containsBlockWithUID (blocksToAdd, info.uid))\r
+ {\r
+ blocksToUpdate.addIfNotAlreadyThere (block);\r
+ shouldTriggerUpdate = true;\r
+ }\r
}\r
}\r
+\r
+ if (shouldTriggerUpdate)\r
+ triggerAsyncUpdate();\r
+ }\r
+\r
+ void handleDeviceUpdated (const DeviceInfo& info)\r
+ {\r
+ handleDevicesUpdated ({ info });\r
}\r
\r
void handleBatteryChargingChanged (Block::UID deviceID, const BlocksProtocol::BatteryCharging isCharging)\r
\r
void handleTimerTick()\r
{\r
- for (auto& b : detector->currentTopology.blocks)\r
- if (auto bi = BlockImplementation<Detector>::getFrom (*b))\r
- bi->handleTimerTick();\r
+ auto blocks = detector->currentTopology.blocks;\r
+\r
+ if (blocks.size() == 0)\r
+ return;\r
+\r
+ if (nextIndexToTick >= blocks.size())\r
+ nextIndexToTick = 0;\r
+\r
+ if (auto* bi = BlockImplementation<Detector>::getFrom (*blocks [nextIndexToTick]))\r
+ bi->handleTimerTick();\r
+\r
+ nextIndexToTick = (nextIndexToTick + 1) % blocks.size();\r
}\r
\r
PhysicalTopologySource& topologySource;\r
Detector::Ptr detector;\r
+\r
+ int nextIndexToTick {0};\r
};\r
\r
} // namespace juce\r
{\r
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED // This method must only be called from the message thread!\r
\r
- jassert (dataSize > sizeof (BlocksProtocol::roliSysexHeader) + 2);\r
+ jassert (dataSize > sizeof (BlocksProtocol::roliSysexHeader) + 1);\r
jassert (memcmp (data, BlocksProtocol::roliSysexHeader, sizeof (BlocksProtocol::roliSysexHeader) - 1) == 0);\r
jassert (static_cast<const uint8*> (data)[dataSize - 1] == 0xf7);\r
\r
\r
//==============================================================================\r
/** These can be useful when debugging the topology. */\r
-#define LOG_BLOCKS_CONNECTIVITY 0\r
-#define LOG_BLOCKS_PINGS 0\r
-#define DUMP_BANDWIDTH_STATS 0\r
-#define DUMP_TOPOLOGY 0\r
+\r
+#ifndef LOG_BLOCKS_CONNECTIVITY\r
+ #define LOG_BLOCKS_CONNECTIVITY 0\r
+#endif\r
+\r
+#ifndef LOG_BLOCKS_PINGS\r
+ #define LOG_BLOCKS_PINGS 0\r
+#endif\r
+\r
+#ifndef DUMP_BANDWIDTH_STATS\r
+ #define DUMP_BANDWIDTH_STATS 0\r
+#endif\r
+\r
+#ifndef DUMP_TOPOLOGY\r
+ #define DUMP_TOPOLOGY 0\r
+#endif\r
\r
#define TOPOLOGY_LOG(text) \\r
JUCE_BLOCK_WITH_FORCED_SEMICOLON (juce::String buf ("Topology Src: "); \\r
#include "internal/juce_MIDIDeviceDetector.cpp"\r
#include "internal/juce_DeviceInfo.cpp"\r
#include "internal/juce_DepreciatedVersionReader.cpp"\r
+#include "internal/juce_BlockSerialReader.cpp"\r
#include "internal/juce_ConnectedDeviceGroup.cpp"\r
#include "internal/juce_BlockImplementation.cpp"\r
#include "internal/juce_Detector.cpp"\r
/** This method will tell, if an other PhysicalTopologySource has locked the Midi connection */\r
bool isLockedFromOutside() const;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** For custom transport systems, this represents a connected device */\r
struct DeviceConnection\r
{\r
virtual void handleTimerTick();\r
\r
private:\r
- //==========================================================================\r
+ //==============================================================================\r
DeviceDetector* customDetector = nullptr;\r
friend struct Detector;\r
struct DetectorHolder;\r
/** Destructor. */\r
~RuleBasedTopologySource() override;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Returns the currently active topology. */\r
BlockTopology getCurrentTopology() const override;\r
\r
bool isActive() const override;\r
\r
private:\r
- //==========================================================================\r
+ //==============================================================================\r
struct Internal;\r
std::unique_ptr<Internal> internal;\r
};\r
class TopologySource\r
{\r
public:\r
- //==========================================================================\r
+ //==============================================================================\r
/** Destructor. */\r
virtual ~TopologySource() = default;\r
\r
/** Returns true, if the TopologySource is currently trying to connect the block devices */\r
virtual bool isActive() const = 0;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Used to receive callbacks for topology changes */\r
struct Listener\r
{\r
virtual void cancelAllActiveTouches() noexcept {}\r
\r
protected:\r
- //==========================================================================\r
+ //==============================================================================\r
ListenerList<Listener> listeners;\r
};\r
\r
\r
ID: juce_box2d\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE wrapper for the Box2D physics engine\r
description: The Box2D physics engine and some utility classes.\r
website: http://www.juce.com/juce\r
\r
/** Returns the value of a named item.\r
If the name isn't found, this will return a void variant.\r
- @see getProperty\r
*/\r
const var& operator[] (const Identifier& name) const noexcept;\r
\r
//==============================================================================\r
/** Appends a new object to the end of the array.\r
\r
- Note that the this object will be deleted by the OwnedArray when it\r
- is removed, so be careful not to delete it somewhere else.\r
+ Note that this object will be deleted by the OwnedArray when it is removed,\r
+ so be careful not to delete it somewhere else.\r
\r
Also be careful not to add the same object to the array more than once,\r
as this will obviously cause deletion of dangling pointers.\r
\r
@param newObject the new object to add to the array\r
@returns the new object that was added\r
- @see set, insert, addIfNotAlreadyThere, addSorted\r
+ @see set, insert, addSorted\r
*/\r
ObjectClass* add (ObjectClass* newObject)\r
{\r
\r
/** Appends a new object to the end of the array.\r
\r
- Note that the this object will be deleted by the OwnedArray when it\r
- is removed, so be careful not to delete it somewhere else.\r
+ Note that this object will be deleted by the OwnedArray when it is removed,\r
+ so be careful not to delete it somewhere else.\r
\r
Also be careful not to add the same object to the array more than once,\r
as this will obviously cause deletion of dangling pointers.\r
\r
@param newObject the new object to add to the array\r
@returns the new object that was added\r
- @see set, insert, addIfNotAlreadyThere, addSorted\r
+ @see set, insert, addSorted\r
*/\r
ObjectClass* add (std::unique_ptr<ObjectClass> newObject)\r
{\r
\r
/** Inserts a new object into the array at the given index.\r
\r
- Note that the this object will be deleted by the OwnedArray when it\r
- is removed, so be careful not to delete it somewhere else.\r
+ Note that this object will be deleted by the OwnedArray when it is removed,\r
+ so be careful not to delete it somewhere else.\r
\r
If the index is less than 0 or greater than the size of the array, the\r
element will be added to the end of the array.\r
@param indexToInsertAt the index at which the new element should be inserted\r
@param newObject the new object to add to the array\r
@returns the new object that was added\r
- @see add, addSorted, addIfNotAlreadyThere, set\r
+ @see add, addSorted, set\r
*/\r
ObjectClass* insert (int indexToInsertAt, ObjectClass* newObject)\r
{\r
\r
/** Inserts a new object into the array at the given index.\r
\r
- Note that the this object will be deleted by the OwnedArray when it\r
- is removed, so be careful not to delete it somewhere else.\r
+ Note that this object will be deleted by the OwnedArray when it is removed,\r
+ so be careful not to delete it somewhere else.\r
\r
If the index is less than 0 or greater than the size of the array, the\r
element will be added to the end of the array.\r
@param indexToInsertAt the index at which the new element should be inserted\r
@param newObject the new object to add to the array\r
@returns the new object that was added\r
- @see add, addSorted, addIfNotAlreadyThere, set\r
+ @see add, addSorted, set\r
*/\r
ObjectClass* insert (int indexToInsertAt, std::unique_ptr<ObjectClass> newObject)\r
{\r
\r
expect (demoFolder.deleteRecursively());\r
expect (! demoFolder.exists());\r
+\r
+ {\r
+ URL url ("https://audio.dev/foo/bar/");\r
+ expectEquals (url.toString (false), String ("https://audio.dev/foo/bar/"));\r
+ expectEquals (url.getChildURL ("x").toString (false), String ("https://audio.dev/foo/bar/x"));\r
+ expectEquals (url.getParentURL().toString (false), String ("https://audio.dev/foo"));\r
+ expectEquals (url.getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));\r
+ expectEquals (url.getParentURL().getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));\r
+ expectEquals (url.getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/foo/x"));\r
+ expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/x"));\r
+ }\r
+\r
+ {\r
+ URL url ("https://audio.dev/foo/bar");\r
+ expectEquals (url.toString (false), String ("https://audio.dev/foo/bar"));\r
+ expectEquals (url.getChildURL ("x").toString (false), String ("https://audio.dev/foo/bar/x"));\r
+ expectEquals (url.getParentURL().toString (false), String ("https://audio.dev/foo"));\r
+ expectEquals (url.getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));\r
+ expectEquals (url.getParentURL().getParentURL().getParentURL().toString (false), String ("https://audio.dev/"));\r
+ expectEquals (url.getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/foo/x"));\r
+ expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/x"));\r
+ }\r
}\r
};\r
\r
#endif\r
\r
#if JUCE_BELA\r
- #include <native/timer.h>\r
+ #include <alchemy/timer.h>\r
#endif\r
\r
#undef check\r
\r
ID: juce_core\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE core classes\r
description: The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.\r
website: http://www.juce.com/juce\r
{\r
if (! shouldDelete)\r
object.release();\r
+ else\r
+ object.reset();\r
}\r
\r
/** Does the same thing as reset(). */\r
static bool JUCE_CALLTYPE valueExists (const String& regValuePath, WoW64Mode mode = WoW64_Default);\r
\r
/** Returns true if the given key exists in the registry. */\r
- static bool JUCE_CALLTYPE keyExists (const String& regValuePath, WoW64Mode mode = WoW64_Default);\r
+ static bool JUCE_CALLTYPE keyExists (const String& regKeyPath, WoW64Mode mode = WoW64_Default);\r
\r
/** Deletes a registry value. */\r
static bool JUCE_CALLTYPE deleteValue (const String& regValuePath, WoW64Mode mode = WoW64_Default);\r
#include <objc/runtime.h>\r
#include <objc/objc.h>\r
#include <objc/message.h>\r
+ #include <poll.h>\r
\r
//==============================================================================\r
#elif JUCE_WINDOWS\r
#include <sys/vfs.h>\r
#include <sys/wait.h>\r
#include <utime.h>\r
+ #include <poll.h>\r
\r
//==============================================================================\r
#elif JUCE_BSD\r
#include <sys/types.h>\r
#include <sys/wait.h>\r
#include <utime.h>\r
+ #include <poll.h>\r
\r
//==============================================================================\r
#elif JUCE_ANDROID\r
#include <fnmatch.h>\r
#include <sys/wait.h>\r
#include <android/api-level.h>\r
+ #include <poll.h>\r
\r
// If you are getting include errors here, then you to re-build the Projucer\r
// and re-save your .jucer file.\r
auto activity = env->GetArrayLength (args) > 0 ? env->GetObjectArrayElement (args, 0) : (jobject) nullptr;\r
auto bundle = env->GetArrayLength (args) > 1 ? env->GetObjectArrayElement (args, 1) : (jobject) nullptr;\r
\r
- if (methodName == "onActivityCreated") { onActivityCreated (activity, bundle); return nullptr; }\r
- else if (methodName == "onActivityDestroyed") { onActivityDestroyed (activity); return nullptr; }\r
- else if (methodName == "onActivityPaused") { onActivityPaused (activity); return nullptr; }\r
- else if (methodName == "onActivityResumed") { onActivityResumed (activity); return nullptr; }\r
- else if (methodName == "onActivitySaveInstanceState") { onActivitySaveInstanceState (activity, bundle); return nullptr; }\r
- else if (methodName == "onActivityStarted") { onActivityStarted (activity); return nullptr; }\r
- else if (methodName == "onActivityStopped") { onActivityStopped (activity); return nullptr; }\r
+ if (methodName == "onActivityPreCreated") { onActivityPreCreated (activity, bundle); return nullptr; }\r
+ else if (methodName == "onActivityPreDestroyed") { onActivityPreDestroyed (activity); return nullptr; }\r
+ else if (methodName == "onActivityPrePaused") { onActivityPrePaused (activity); return nullptr; }\r
+ else if (methodName == "onActivityPreResumed") { onActivityPreResumed (activity); return nullptr; }\r
+ else if (methodName == "onActivityPreSaveInstanceState") { onActivityPreSaveInstanceState (activity, bundle); return nullptr; }\r
+ else if (methodName == "onActivityPreStarted") { onActivityPreStarted (activity); return nullptr; }\r
+ else if (methodName == "onActivityPreStopped") { onActivityPreStopped (activity); return nullptr; }\r
+ else if (methodName == "onActivityCreated") { onActivityCreated (activity, bundle); return nullptr; }\r
+ else if (methodName == "onActivityDestroyed") { onActivityDestroyed (activity); return nullptr; }\r
+ else if (methodName == "onActivityPaused") { onActivityPaused (activity); return nullptr; }\r
+ else if (methodName == "onActivityResumed") { onActivityResumed (activity); return nullptr; }\r
+ else if (methodName == "onActivitySaveInstanceState") { onActivitySaveInstanceState (activity, bundle); return nullptr; }\r
+ else if (methodName == "onActivityStarted") { onActivityStarted (activity); return nullptr; }\r
+ else if (methodName == "onActivityStopped") { onActivityStopped (activity); return nullptr; }\r
+ else if (methodName == "onActivityPostCreated") { onActivityPostCreated (activity, bundle); return nullptr; }\r
+ else if (methodName == "onActivityPostDestroyed") { onActivityPostDestroyed (activity); return nullptr; }\r
+ else if (methodName == "onActivityPostPaused") { onActivityPostPaused (activity); return nullptr; }\r
+ else if (methodName == "onActivityPostResumed") { onActivityPostResumed (activity); return nullptr; }\r
+ else if (methodName == "onActivityPostSaveInstanceState") { onActivityPostSaveInstanceState (activity, bundle); return nullptr; }\r
+ else if (methodName == "onActivityPostStarted") { onActivityPostStarted (activity); return nullptr; }\r
+ else if (methodName == "onActivityPostStopped") { onActivityPostStopped (activity); return nullptr; }\r
\r
return AndroidInterfaceImplementer::invoke (proxy, method, args);\r
}\r
class ActivityLifecycleCallbacks : public AndroidInterfaceImplementer\r
{\r
public:\r
- virtual void onActivityCreated (jobject /*activity*/, jobject /*bundle*/) {}\r
- virtual void onActivityDestroyed (jobject /*activity*/) {}\r
- virtual void onActivityPaused (jobject /*activity*/) {}\r
- virtual void onActivityResumed (jobject /*activity*/) {}\r
- virtual void onActivitySaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {}\r
- virtual void onActivityStarted (jobject /*activity*/) {}\r
- virtual void onActivityStopped (jobject /*activity*/) {}\r
+ virtual void onActivityPreCreated (jobject /*activity*/, jobject /*bundle*/) {}\r
+ virtual void onActivityPreDestroyed (jobject /*activity*/) {}\r
+ virtual void onActivityPrePaused (jobject /*activity*/) {}\r
+ virtual void onActivityPreResumed (jobject /*activity*/) {}\r
+ virtual void onActivityPreSaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {}\r
+ virtual void onActivityPreStarted (jobject /*activity*/) {}\r
+ virtual void onActivityPreStopped (jobject /*activity*/) {}\r
+\r
+ virtual void onActivityCreated (jobject /*activity*/, jobject /*bundle*/) {}\r
+ virtual void onActivityDestroyed (jobject /*activity*/) {}\r
+ virtual void onActivityPaused (jobject /*activity*/) {}\r
+ virtual void onActivityResumed (jobject /*activity*/) {}\r
+ virtual void onActivitySaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {}\r
+ virtual void onActivityStarted (jobject /*activity*/) {}\r
+ virtual void onActivityStopped (jobject /*activity*/) {}\r
+\r
+ virtual void onActivityPostCreated (jobject /*activity*/, jobject /*bundle*/) {}\r
+ virtual void onActivityPostDestroyed (jobject /*activity*/) {}\r
+ virtual void onActivityPostPaused (jobject /*activity*/) {}\r
+ virtual void onActivityPostResumed (jobject /*activity*/) {}\r
+ virtual void onActivityPostSaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {}\r
+ virtual void onActivityPostStarted (jobject /*activity*/) {}\r
+ virtual void onActivityPostStopped (jobject /*activity*/) {}\r
\r
private:\r
jobject invoke (jobject, jobject, jobjectArray) override;\r
bytesToRead = static_cast<int> (chunkEnd - position);\r
}\r
\r
- fd_set readbits;\r
- FD_ZERO (&readbits);\r
- FD_SET (socketHandle, &readbits);\r
+ pollfd pfd { socketHandle, POLLIN, 0 };\r
\r
- struct timeval tv;\r
- tv.tv_sec = jmax (1, timeOutMs / 1000);\r
- tv.tv_usec = 0;\r
-\r
- if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)\r
- return 0; // (timeout)\r
+ if (poll (&pfd, 1, timeOutMs) <= 0)\r
+ return 0; // (timeout)\r
\r
auto bytesRead = jmax (0, (int) recv (socketHandle, buffer, (size_t) bytesToRead, MSG_WAITALL));\r
\r
\r
static void waitForInput (int handle, int timeoutMsecs) noexcept\r
{\r
- struct timeval timeout;\r
- timeout.tv_sec = timeoutMsecs / 1000;\r
- timeout.tv_usec = (timeoutMsecs % 1000) * 1000;\r
-\r
- fd_set rset;\r
- FD_ZERO (&rset);\r
- FD_SET (handle, &rset);\r
-\r
- select (handle + 1, &rset, nullptr, nullptr, &timeout);\r
+ pollfd pfd { handle, POLLIN, 0 };\r
+ poll (&pfd, 1, timeoutMsecs);\r
}\r
\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)\r
\r
if (juce_stat (fullPath, info))\r
{\r
+ #if JUCE_MAC || (JUCE_IOS && __DARWIN_ONLY_64_BIT_INO_T)\r
+ modificationTime = (int64) info.st_mtimespec.tv_sec * 1000 + info.st_mtimespec.tv_nsec / 1000000;\r
+ accessTime = (int64) info.st_atimespec.tv_sec * 1000 + info.st_atimespec.tv_nsec / 1000000;\r
+ creationTime = (int64) info.st_birthtimespec.tv_sec * 1000 + info.st_birthtimespec.tv_nsec / 1000000;\r
+ #else\r
modificationTime = (int64) info.st_mtime * 1000;\r
accessTime = (int64) info.st_atime * 1000;\r
- #if JUCE_MAC || JUCE_IOS\r
+ #if JUCE_IOS\r
creationTime = (int64) info.st_birthtime * 1000;\r
#else\r
creationTime = (int64) info.st_ctime * 1000;\r
#endif\r
+ #endif\r
}\r
}\r
\r
\r
if ((modificationTime != 0 || accessTime != 0) && juce_stat (fullPath, info))\r
{\r
+ #if JUCE_MAC || (JUCE_IOS && __DARWIN_ONLY_64_BIT_INO_T)\r
+ struct timeval times[2];\r
+\r
+ bool setModificationTime = (modificationTime != 0);\r
+ bool setAccessTime = (accessTime != 0);\r
+\r
+ times[0].tv_sec = setAccessTime ? static_cast<__darwin_time_t> (accessTime / 1000)\r
+ : info.st_atimespec.tv_sec;\r
+\r
+ times[0].tv_usec = setAccessTime ? static_cast<__darwin_suseconds_t> ((accessTime % 1000) * 1000)\r
+ : static_cast<__darwin_suseconds_t> (info.st_atimespec.tv_nsec / 1000);\r
+\r
+ times[1].tv_sec = setModificationTime ? static_cast<__darwin_time_t> (modificationTime / 1000)\r
+ : info.st_mtimespec.tv_sec;\r
+\r
+ times[1].tv_usec = setModificationTime ? static_cast<__darwin_suseconds_t> ((modificationTime % 1000) * 1000)\r
+ : static_cast<__darwin_suseconds_t> (info.st_mtimespec.tv_nsec / 1000);\r
+\r
+ return utimes (fullPath.toUTF8(), times) == 0;\r
+ #else\r
struct utimbuf times;\r
times.actime = accessTime != 0 ? static_cast<time_t> (accessTime / 1000) : static_cast<time_t> (info.st_atime);\r
times.modtime = modificationTime != 0 ? static_cast<time_t> (modificationTime / 1000) : static_cast<time_t> (info.st_mtime);\r
\r
return utime (fullPath.toUTF8(), ×) == 0;\r
+ #endif\r
}\r
\r
return false;\r
\r
~RegistryKeyWrapper()\r
{\r
- if (key != 0)\r
+ if (key != nullptr)\r
RegCloseKey (key);\r
}\r
\r
{\r
const RegistryKeyWrapper key (regValuePath, true, wow64Flags);\r
\r
- return key.key != 0\r
+ return key.key != nullptr\r
&& RegSetValueEx (key.key, key.wideCharValueName, 0, type,\r
reinterpret_cast<const BYTE*> (data),\r
(DWORD) dataSize) == ERROR_SUCCESS;\r
{\r
const RegistryKeyWrapper key (regValuePath, false, wow64Flags);\r
\r
- if (key.key != 0)\r
+ if (key.key != nullptr)\r
{\r
for (unsigned long bufferSize = 1024; ; bufferSize *= 2)\r
{\r
return defaultValue;\r
}\r
\r
- static bool keyExists (const String& regValuePath, const DWORD wow64Flags)\r
+ static bool keyExists (const String& regKeyPath, const DWORD wow64Flags)\r
{\r
- return RegistryKeyWrapper (regValuePath, false, wow64Flags).key != 0;\r
+ return RegistryKeyWrapper (regKeyPath + "\\", false, wow64Flags).key != nullptr;\r
}\r
\r
static bool valueExists (const String& regValuePath, const DWORD wow64Flags)\r
{\r
const RegistryKeyWrapper key (regValuePath, false, wow64Flags);\r
\r
- if (key.key == 0)\r
+ if (key.key == nullptr)\r
return false;\r
\r
unsigned char buffer [512];\r
return result == ERROR_SUCCESS || result == ERROR_MORE_DATA;\r
}\r
\r
- HKEY key = 0;\r
+ HKEY key = nullptr;\r
const wchar_t* wideCharValueName = nullptr;\r
String valueName;\r
\r
return RegistryKeyWrapper::valueExists (regValuePath, (DWORD) mode);\r
}\r
\r
-bool JUCE_CALLTYPE WindowsRegistry::keyExists (const String& regValuePath, WoW64Mode mode)\r
+bool JUCE_CALLTYPE WindowsRegistry::keyExists (const String& regKeyPath, WoW64Mode mode)\r
{\r
- return RegistryKeyWrapper::keyExists (regValuePath, (DWORD) mode);\r
+ return RegistryKeyWrapper::keyExists (regKeyPath, (DWORD) mode);\r
}\r
\r
bool JUCE_CALLTYPE WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode)\r
{\r
const RegistryKeyWrapper key (regValuePath, true, (DWORD) mode);\r
\r
- return key.key != 0 && RegDeleteValue (key.key, key.wideCharValueName) == ERROR_SUCCESS;\r
+ return key.key != nullptr && RegDeleteValue (key.key, key.wideCharValueName) == ERROR_SUCCESS;\r
}\r
\r
static bool deleteKeyNonRecursive (const String& regKeyPath, WindowsRegistry::WoW64Mode mode)\r
{\r
const RegistryKeyWrapper key (regKeyPath, true, (DWORD) mode);\r
\r
- return key.key != 0 && RegDeleteKey (key.key, key.wideCharValueName) == ERROR_SUCCESS;\r
+ return key.key != nullptr && RegDeleteKey (key.key, key.wideCharValueName) == ERROR_SUCCESS;\r
}\r
\r
bool JUCE_CALLTYPE WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode)\r
#endif\r
\r
#if JUCE_WINDOWS\r
- typedef int juce_socklen_t;\r
- typedef int juce_recvsend_size_t;\r
- typedef SOCKET SocketHandle;\r
+ using juce_socklen_t = int;\r
+ using juce_recvsend_size_t = int;\r
+ using SocketHandle = SOCKET;\r
+ #if ! JUCE_MINGW\r
+ using pollfd = WSAPOLLFD;\r
+ #endif\r
static const SocketHandle invalidSocket = INVALID_SOCKET;\r
#elif JUCE_ANDROID\r
- typedef socklen_t juce_socklen_t;\r
- typedef size_t juce_recvsend_size_t;\r
- typedef int SocketHandle;\r
+ using juce_socklen_t = socklen_t;\r
+ using juce_recvsend_size_t = size_t;\r
+ using SocketHandle = int;\r
static const SocketHandle invalidSocket = -1;\r
#else\r
- typedef socklen_t juce_socklen_t;\r
- typedef socklen_t juce_recvsend_size_t;\r
- typedef int SocketHandle;\r
+ using juce_socklen_t = socklen_t;\r
+ using juce_recvsend_size_t = socklen_t;\r
+ using SocketHandle = int;\r
static const SocketHandle invalidSocket = -1;\r
#endif\r
\r
\r
static bool resetSocketOptions (SocketHandle handle, bool isDatagram, bool allowBroadcast) noexcept\r
{\r
- return handle >= 0\r
+ return handle != invalidSocket\r
&& setOption (handle, SO_RCVBUF, (int) 65536)\r
&& setOption (handle, SO_SNDBUF, (int) 65536)\r
&& (isDatagram ? ((! allowBroadcast) || setOption (handle, SO_BROADCAST, (int) 1))\r
\r
static bool bindSocket (SocketHandle handle, int port, const String& address) noexcept\r
{\r
- if (handle < 0 || ! isValidPortNumber (port))\r
+ if (handle == invalidSocket || ! isValidPortNumber (port))\r
return false;\r
\r
struct sockaddr_in addr;\r
\r
static int getBoundPort (SocketHandle handle) noexcept\r
{\r
- if (handle >= 0)\r
+ if (handle != invalidSocket)\r
{\r
struct sockaddr_in addr;\r
socklen_t len = sizeof (addr);\r
return "0.0.0.0";\r
}\r
\r
+ static bool setSocketBlockingState (SocketHandle handle, bool shouldBlock) noexcept\r
+ {\r
+ #if JUCE_WINDOWS\r
+ u_long nonBlocking = shouldBlock ? 0 : (u_long) 1;\r
+ return ioctlsocket (handle, FIONBIO, &nonBlocking) == 0;\r
+ #else\r
+ int socketFlags = fcntl (handle, F_GETFL, 0);\r
+\r
+ if (socketFlags == -1)\r
+ return false;\r
+\r
+ if (shouldBlock)\r
+ socketFlags &= ~O_NONBLOCK;\r
+ else\r
+ socketFlags |= O_NONBLOCK;\r
+\r
+ return fcntl (handle, F_SETFL, socketFlags) == 0;\r
+ #endif\r
+ }\r
+\r
+ #if ! JUCE_WINDOWS\r
+ static bool getSocketBlockingState (SocketHandle handle)\r
+ {\r
+ return (fcntl (handle, F_GETFL, 0) & O_NONBLOCK) == 0;\r
+ }\r
+ #endif\r
+\r
static int readSocket (SocketHandle handle,\r
void* destBuffer, int maxBytesToRead,\r
std::atomic<bool>& connected,\r
String* senderIP = nullptr,\r
int* senderPort = nullptr) noexcept\r
{\r
+ #if ! JUCE_WINDOWS\r
+ if (blockUntilSpecifiedAmountHasArrived != getSocketBlockingState (handle))\r
+ #endif\r
+ setSocketBlockingState (handle, blockUntilSpecifiedAmountHasArrived);\r
+\r
int bytesRead = 0;\r
\r
while (bytesRead < maxBytesToRead)\r
if (! lock.isLocked())\r
return -1;\r
\r
- int h = handle.load();\r
+ auto h = handle.load();\r
\r
+ #if JUCE_MINGW\r
struct timeval timeout;\r
struct timeval* timeoutp;\r
\r
fd_set* const prset = forReading ? &rset : nullptr;\r
fd_set* const pwset = forReading ? nullptr : &wset;\r
\r
- #if JUCE_WINDOWS\r
if (select ((int) h + 1, prset, pwset, 0, timeoutp) < 0)\r
return -1;\r
#else\r
- {\r
- int result = 0;\r
+ short eventsFlag = (forReading ? POLLIN : POLLOUT);\r
+ pollfd pfd { (SocketHandle) h, eventsFlag, 0 };\r
\r
- for (;;)\r
- {\r
- result = select (h + 1, prset, pwset, nullptr, timeoutp);\r
+ int result = 0;\r
\r
- if (result >= 0 || errno != EINTR)\r
- break;\r
+ for (;;)\r
+ {\r
+ #if JUCE_WINDOWS\r
+ result = WSAPoll (&pfd, 1, timeoutMsecs);\r
+ #else\r
+ result = poll (&pfd, 1, timeoutMsecs);\r
+ #endif\r
+\r
+ if (result >= 0\r
+ #if JUCE_WINDOWS\r
+ || result == SOCKET_ERROR\r
+ #else\r
+ || errno != EINTR\r
+ #endif\r
+ )\r
+ {\r
+ break;\r
}\r
-\r
- if (result < 0)\r
- return -1;\r
}\r
+\r
+ if (result < 0)\r
+ return -1;\r
#endif\r
\r
// we are closing\r
return -1;\r
}\r
\r
+ #if JUCE_MINGW\r
return FD_ISSET (h, forReading ? &rset : &wset) ? 1 : 0;\r
- }\r
-\r
- static bool setSocketBlockingState (SocketHandle handle, bool shouldBlock) noexcept\r
- {\r
- #if JUCE_WINDOWS\r
- u_long nonBlocking = shouldBlock ? 0 : (u_long) 1;\r
- return ioctlsocket (handle, FIONBIO, &nonBlocking) == 0;\r
#else\r
- int socketFlags = fcntl (handle, F_GETFL, 0);\r
-\r
- if (socketFlags == -1)\r
- return false;\r
-\r
- if (shouldBlock)\r
- socketFlags &= ~O_NONBLOCK;\r
- else\r
- socketFlags |= O_NONBLOCK;\r
-\r
- return fcntl (handle, F_SETFL, socketFlags) == 0;\r
+ return (pfd.revents & eventsFlag) != 0;\r
#endif\r
}\r
\r
return -1;\r
\r
std::atomic<bool> connected { true };\r
-\r
- SocketHelpers::setSocketBlockingState (handle, shouldBlock);\r
return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead,\r
connected, shouldBlock, readLock);\r
}\r
return -1;\r
\r
std::atomic<bool> connected { true };\r
-\r
- SocketHelpers::setSocketBlockingState (handle, shouldBlock);\r
return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, connected,\r
shouldBlock, readLock, &senderIPAddress, &senderPort);\r
}\r
URL::DownloadTask::~DownloadTask() {}\r
\r
//==============================================================================\r
-URL::URL() noexcept {}\r
+URL::URL() {}\r
\r
URL::URL (const String& u) : url (u)\r
{\r
url = "/" + url;\r
}\r
\r
-\r
url = "file://" + url;\r
\r
jassert (isWellFormed());\r
else\r
path += suffix;\r
}\r
+\r
+ static String removeLastPathSection (const String& url)\r
+ {\r
+ auto startOfPath = findStartOfPath (url);\r
+ auto lastSlash = url.lastIndexOfChar ('/');\r
+\r
+ if (lastSlash > startOfPath && lastSlash == url.length() - 1)\r
+ return removeLastPathSection (url.dropLastCharacters (1));\r
+\r
+ if (lastSlash < 0)\r
+ return url;\r
+\r
+ return url.substring (0, std::max (startOfPath, lastSlash));\r
+ }\r
}\r
\r
void URL::addParameter (const String& name, const String& value)\r
return url.substring (0, URLHelpers::findEndOfScheme (url) - 1);\r
}\r
\r
-#ifndef JUCE_ANDROID\r
+#if ! JUCE_ANDROID\r
bool URL::isLocalFile() const\r
{\r
- return (getScheme() == "file");\r
+ return getScheme() == "file";\r
}\r
\r
File URL::getLocalFile() const\r
\r
auto path = removeEscapeChars (fileURL.getDomainInternal (true)).replace ("+", "%2B");\r
\r
- #ifdef JUCE_WINDOWS\r
+ #if JUCE_WINDOWS\r
bool isUncPath = (! fileURL.url.startsWith ("file:///"));\r
#else\r
path = File::getSeparatorString() + path;\r
for (auto urlElement : urlElements)\r
path += File::getSeparatorString() + removeEscapeChars (urlElement.replace ("+", "%2B"));\r
\r
- #ifdef JUCE_WINDOWS\r
+ #if JUCE_WINDOWS\r
if (isUncPath)\r
path = "\\\\" + path;\r
#endif\r
\r
URL URL::withNewSubPath (const String& newPath) const\r
{\r
- const int startOfPath = URLHelpers::findStartOfPath (url);\r
-\r
URL u (*this);\r
\r
+ auto startOfPath = URLHelpers::findStartOfPath (url);\r
+\r
if (startOfPath > 0)\r
u.url = url.substring (0, startOfPath);\r
\r
return u;\r
}\r
\r
+URL URL::getParentURL() const\r
+{\r
+ URL u (*this);\r
+ u.url = URLHelpers::removeLastPathSection (u.url);\r
+ return u;\r
+}\r
+\r
URL URL::getChildURL (const String& subPath) const\r
{\r
URL u (*this);\r
//==============================================================================\r
bool URL::isProbablyAWebsiteURL (const String& possibleURL)\r
{\r
- static const char* validProtocols[] = { "http:", "ftp:", "https:" };\r
-\r
- for (auto* protocol : validProtocols)\r
+ for (auto* protocol : { "http:", "https:", "ftp:" })\r
if (possibleURL.startsWithIgnoreCase (protocol))\r
return true;\r
\r
- if (possibleURL.containsChar ('@')\r
- || possibleURL.containsChar (' '))\r
+ if (possibleURL.containsChar ('@') || possibleURL.containsChar (' '))\r
return false;\r
\r
- const String topLevelDomain (possibleURL.upToFirstOccurrenceOf ("/", false, false)\r
- .fromLastOccurrenceOf (".", false, false));\r
+ auto topLevelDomain = possibleURL.upToFirstOccurrenceOf ("/", false, false)\r
+ .fromLastOccurrenceOf (".", false, false);\r
\r
return topLevelDomain.isNotEmpty() && topLevelDomain.length() <= 3;\r
}\r
}\r
\r
#if JUCE_IOS\r
-URL::Bookmark::Bookmark (void* bookmarkToUse)\r
- : data (bookmarkToUse)\r
+URL::Bookmark::Bookmark (void* bookmarkToUse) : data (bookmarkToUse)\r
{\r
}\r
\r
\r
return urlToUse.getLocalFile();\r
}\r
- else\r
- {\r
- auto desc = [error localizedDescription];\r
- ignoreUnused (desc);\r
- jassertfalse;\r
- }\r
+\r
+ auto desc = [error localizedDescription];\r
+ ignoreUnused (desc);\r
+ jassertfalse;\r
}\r
\r
return urlToUse.getLocalFile();\r
#else\r
return getLocalFile().createInputStream();\r
#endif\r
-\r
}\r
\r
- std::unique_ptr<WebInputStream> wi (new WebInputStream (*this, usePostCommand));\r
+ auto wi = std::make_unique<WebInputStream> (*this, usePostCommand);\r
\r
struct ProgressCallbackCaller : public WebInputStream::Listener\r
{\r
public:\r
//==============================================================================\r
/** Creates an empty URL. */\r
- URL() noexcept;\r
+ URL();\r
\r
/** Creates a URL from a string.\r
This will parse any embedded parameters after a '?' character and store them\r
*/\r
URL withNewSubPath (const String& newPath) const;\r
\r
+ /** Attempts to return a URL which is the parent folder containing this URL.\r
+ If there isn't a parent, this method will just return a copy of this URL.\r
+ */\r
+ URL getParentURL() const;\r
+\r
/** Returns a new URL that refers to a sub-path relative to this one.\r
E.g. if the URL is "http://www.xyz.com/foo" and you call this with\r
"bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for\r
URL withPOSTData (const MemoryBlock& postData) const;\r
\r
/** Returns the data that was set using withPOSTData(). */\r
- String getPostData() const noexcept { return postData.toString(); }\r
+ String getPostData() const { return postData.toString(); }\r
\r
/** Returns the data that was set using withPOSTData() as MemoryBlock. */\r
const MemoryBlock& getPostDataAsMemoryBlock() const noexcept { return postData; }\r
InputStream* createInputStream (bool doPostLikeRequest,\r
OpenStreamProgressCallback* progressCallback = nullptr,\r
void* progressCallbackContext = nullptr,\r
- String extraHeaders = String(),\r
+ String extraHeaders = {},\r
int connectionTimeOutMs = 0,\r
StringPairArray* responseHeaders = nullptr,\r
int* statusCode = nullptr,\r
int numRedirectsToFollow = 5,\r
- String httpRequestCmd = String()) const;\r
+ String httpRequestCmd = {}) const;\r
\r
/** Attempts to open an output stream to a URL for writing\r
\r
template<typename T, typename... Args>\r
unique_ptr<T> make_unique (Args&&... args)\r
{\r
- return unique_ptr<T> (new T (forward<Args> (args)...));\r
+ return unique_ptr<T> (new T (std::forward<Args> (args)...));\r
}\r
}\r
#endif\r
*/\r
#define JUCE_MAJOR_VERSION 5\r
#define JUCE_MINOR_VERSION 4\r
-#define JUCE_BUILDNUMBER 4\r
+#define JUCE_BUILDNUMBER 5\r
\r
/** Current JUCE version number.\r
\r
\r
PerformanceCounter::~PerformanceCounter()\r
{\r
- printStatistics();\r
+ if (stats.numRuns > 0)\r
+ printStatistics();\r
}\r
\r
PerformanceCounter::Statistics::Statistics() noexcept\r
\r
ID: juce_cryptography\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE cryptography classes\r
description: Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.\r
website: http://www.juce.com/juce\r
\r
ID: juce_data_structures\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE data model helper classes\r
description: Classes for undo/redo management, and smart data structures.\r
website: http://www.juce.com/juce\r
\r
//==============================================================================\r
/** Create a zero-sized AudioBlock. */\r
- forcedinline AudioBlock() noexcept = default;\r
+ AudioBlock() noexcept = default;\r
\r
/** Creates an AudioBlock from a pointer to an array of channels.\r
AudioBlock does not copy nor own the memory pointed to by dataToUse.\r
Therefore it is the user's responsibility to ensure that the memory is retained\r
throughout the life-time of the AudioBlock and released when no longer needed.\r
*/\r
- forcedinline AudioBlock (SampleType* const* channelData,\r
- size_t numberOfChannels, size_t numberOfSamples) noexcept\r
+ constexpr AudioBlock (SampleType* const* channelData,\r
+ size_t numberOfChannels, size_t numberOfSamples) noexcept\r
: channels (channelData),\r
numChannels (static_cast<ChannelCountType> (numberOfChannels)),\r
numSamples (numberOfSamples)\r
Therefore it is the user's responsibility to ensure that the memory is retained\r
throughout the life-time of the AudioBlock and released when no longer needed.\r
*/\r
- forcedinline AudioBlock (SampleType* const* channelData, size_t numberOfChannels,\r
- size_t startSampleIndex, size_t numberOfSamples) noexcept\r
+ constexpr AudioBlock (SampleType* const* channelData, size_t numberOfChannels,\r
+ size_t startSampleIndex, size_t numberOfSamples) noexcept\r
: channels (channelData),\r
numChannels (static_cast<ChannelCountType> (numberOfChannels)),\r
startSample (startSampleIndex),\r
throughout the life-time of the AudioBlock without being modified.\r
*/\r
template <typename OtherSampleType>\r
- AudioBlock (AudioBuffer<OtherSampleType>& buffer) noexcept\r
+ constexpr AudioBlock (AudioBuffer<OtherSampleType>& buffer) noexcept\r
: channels (buffer.getArrayOfWritePointers()),\r
numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())),\r
numSamples (static_cast<size_t> (buffer.getNumSamples()))\r
\r
//==============================================================================\r
template <typename OtherSampleType>\r
- bool operator== (const AudioBlock<OtherSampleType>& other) const noexcept\r
+ constexpr bool operator== (const AudioBlock<OtherSampleType>& other) const noexcept\r
{\r
return std::equal (channels,\r
channels + numChannels,\r
}\r
\r
template <typename OtherSampleType>\r
- bool operator!= (const AudioBlock<OtherSampleType>& other) const noexcept\r
+ constexpr bool operator!= (const AudioBlock<OtherSampleType>& other) const noexcept\r
{\r
return ! (*this == other);\r
}\r
\r
//==============================================================================\r
- forcedinline size_t getNumSamples() const noexcept { return numSamples; }\r
- forcedinline size_t getNumChannels() const noexcept { return static_cast<size_t> (numChannels); }\r
+ /** Returns the number of channels referenced by this block. */\r
+ constexpr size_t getNumChannels() const noexcept { return static_cast<size_t> (numChannels); }\r
\r
- /** Returns a raw pointer into one of the channels in this block. */\r
- forcedinline const SampleType* getChannelPointer (size_t channel) const noexcept\r
- {\r
- jassert (channel < numChannels);\r
- jassert (numSamples > 0);\r
- return channels[channel] + startSample;\r
- }\r
+ /** Returns the number of samples referenced by this block. */\r
+ constexpr size_t getNumSamples() const noexcept { return numSamples; }\r
\r
/** Returns a raw pointer into one of the channels in this block. */\r
- forcedinline SampleType* getChannelPointer (size_t channel) noexcept\r
+ SampleType* getChannelPointer (size_t channel) const noexcept\r
{\r
jassert (channel < numChannels);\r
jassert (numSamples > 0);\r
}\r
\r
/** Returns an AudioBlock that represents one of the channels in this block. */\r
- forcedinline AudioBlock getSingleChannelBlock (size_t channel) const noexcept\r
+ AudioBlock getSingleChannelBlock (size_t channel) const noexcept\r
{\r
jassert (channel < numChannels);\r
return AudioBlock (channels + channel, 1, startSample, numSamples);\r
@param channelStart First channel of the subset\r
@param numChannelsToUse Count of channels in the subset\r
*/\r
- forcedinline AudioBlock getSubsetChannelBlock (size_t channelStart, size_t numChannelsToUse) const noexcept\r
+ AudioBlock getSubsetChannelBlock (size_t channelStart, size_t numChannelsToUse) const noexcept\r
{\r
jassert (channelStart < numChannels);\r
jassert ((channelStart + numChannelsToUse) <= numChannels);\r
{\r
jassert (isPositiveAndBelow (channel, numChannels));\r
jassert (isPositiveAndBelow (sampleIndex, numSamples));\r
- return channels[channel][startSample + sampleIndex];\r
+ return channels[channel][(size_t) startSample + (size_t) sampleIndex];\r
}\r
\r
/** Modifies a sample in the buffer.\r
an assertion will be thrown, but in a release build, you're into 'undefined behaviour'\r
territory.\r
*/\r
- void setSample (int destChannel, int destSample, SampleType newValue) noexcept\r
+ void setSample (int destChannel, int destSample, SampleType newValue) const noexcept\r
{\r
jassert (isPositiveAndBelow (destChannel, numChannels));\r
jassert (isPositiveAndBelow (destSample, numSamples));\r
- channels[destChannel][startSample + destSample] = newValue;\r
+ channels[destChannel][(size_t) startSample + (size_t) destSample] = newValue;\r
}\r
\r
/** Adds a value to a sample in the buffer.\r
an assertion will be thrown, but in a release build, you're into 'undefined behaviour'\r
territory.\r
*/\r
- void addSample (int destChannel, int destSample, SampleType valueToAdd) noexcept\r
+ void addSample (int destChannel, int destSample, SampleType valueToAdd) const noexcept\r
{\r
jassert (isPositiveAndBelow (destChannel, numChannels));\r
jassert (isPositiveAndBelow (destSample, numSamples));\r
- channels[destChannel][startSample + destSample] += valueToAdd;\r
+ channels[destChannel][(size_t) startSample + (size_t) destSample] += valueToAdd;\r
}\r
\r
//==============================================================================\r
- /** Clear the memory described by this AudioBlock. */\r
- forcedinline AudioBlock& clear() noexcept\r
- {\r
- auto n = static_cast<int> (numSamples * sizeFactor);\r
-\r
- for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::clear (channelPtr (ch), n);\r
+ /** Clears the memory referenced by this AudioBlock. */\r
+ AudioBlock& clear() noexcept { clearInternal(); return *this; }\r
+ const AudioBlock& clear() const noexcept { clearInternal(); return *this; }\r
\r
- return *this;\r
- }\r
-\r
- /** Fill memory with value. */\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE fill (SampleType value) noexcept\r
- {\r
- auto n = static_cast<int> (numSamples * sizeFactor);\r
-\r
- for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::fill (channelPtr (ch), value, n);\r
-\r
- return *this;\r
- }\r
+ /** Fills the memory referenced by this AudioBlock with value. */\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE fill (SampleType value) noexcept { fillInternal (value); return *this; }\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE fill (SampleType value) const noexcept { fillInternal (value); return *this; }\r
\r
- /** Copy the values in src to the receiver. */\r
+ /** Copies the values in src to this block. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& copy (const AudioBlock<OtherSampleType>& src) noexcept\r
- {\r
- auto maxChannels = jmin (src.numChannels, numChannels);\r
- auto n = static_cast<int> (jmin (src.numSamples, numSamples) * sizeFactor);\r
-\r
- for (size_t ch = 0; ch < maxChannels; ++ch)\r
- FloatVectorOperations::copy (channelPtr (ch), src.channelPtr (ch), n);\r
-\r
- return *this;\r
- }\r
+ AudioBlock& copyFrom (const AudioBlock<OtherSampleType>& src) noexcept { copyFromInternal (src); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& copyFrom (const AudioBlock<OtherSampleType>& src) const noexcept { copyFromInternal (src); return *this; }\r
\r
- /** Copy the values from a JUCE's AudioBuffer to the receiver.\r
+ /** Copy the values from a JUCE's AudioBuffer to this block.\r
\r
All indices and sizes are in the receiver's units, i.e. if SampleType is a\r
SIMDRegister then incrementing srcPos by one will increase the sample position\r
in the AudioBuffer's units by a factor of SIMDRegister<SampleType>::SIMDNumElements.\r
*/\r
- forcedinline AudioBlock& copyFrom (const AudioBuffer<NumericType>& src, size_t srcPos = 0, size_t dstPos = 0,\r
- size_t numElements = std::numeric_limits<size_t>::max())\r
- {\r
- auto srclen = static_cast<size_t> (src.getNumSamples()) / sizeFactor;\r
- auto n = static_cast<int> (jmin (srclen - srcPos, numSamples - dstPos, numElements) * sizeFactor);\r
- auto maxChannels = jmin (static_cast<size_t> (src.getNumChannels()), static_cast<size_t> (numChannels));\r
-\r
- for (size_t ch = 0; ch < maxChannels; ++ch)\r
- FloatVectorOperations::copy (channelPtr (ch) + dstPos,\r
- src.getReadPointer (static_cast<int> (ch),\r
- static_cast<int> (srcPos * sizeFactor)),\r
- n);\r
+ template <typename OtherSampleType>\r
+ AudioBlock& copyFrom (const AudioBuffer<OtherSampleType>& src,\r
+ size_t srcPos = 0, size_t dstPos = 0,\r
+ size_t numElements = std::numeric_limits<size_t>::max()) { copyFromInternal (src, srcPos, dstPos, numElements); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& copyFrom (const AudioBuffer<OtherSampleType>& src,\r
+ size_t srcPos = 0, size_t dstPos = 0,\r
+ size_t numElements = std::numeric_limits<size_t>::max()) const { copyFromInternal (src, srcPos, dstPos, numElements); return *this; }\r
\r
- return *this;\r
- }\r
\r
- /** Copy the values from the receiver to a JUCE's AudioBuffer.\r
+ /** Copies the values from this block to an AudioBuffer.\r
\r
All indices and sizes are in the receiver's units, i.e. if SampleType is a\r
SIMDRegister then incrementing dstPos by one will increase the sample position\r
in the AudioBuffer's units by a factor of SIMDRegister<SampleType>::SIMDNumElements.\r
*/\r
- forcedinline const AudioBlock& copyTo (AudioBuffer<NumericType>& dst, size_t srcPos = 0, size_t dstPos = 0,\r
- size_t numElements = std::numeric_limits<size_t>::max()) const\r
+ void copyTo (AudioBuffer<typename std::remove_const<NumericType>::type>& dst, size_t srcPos = 0, size_t dstPos = 0,\r
+ size_t numElements = std::numeric_limits<size_t>::max()) const\r
{\r
auto dstlen = static_cast<size_t> (dst.getNumSamples()) / sizeFactor;\r
auto n = static_cast<int> (jmin (numSamples - srcPos, dstlen - dstPos, numElements) * sizeFactor);\r
for (size_t ch = 0; ch < maxChannels; ++ch)\r
FloatVectorOperations::copy (dst.getWritePointer (static_cast<int> (ch),\r
static_cast<int> (dstPos * sizeFactor)),\r
- channelPtr (ch) + srcPos, n);\r
-\r
- return *this;\r
+ getChannelPointer (ch) + srcPos, n);\r
}\r
\r
- /** Move memory within the receiver from the position srcPos to the position dstPos.\r
+ /** Move memory within this block from the position srcPos to the position dstPos.\r
If numElements is not specified then move will move the maximum amount of memory.\r
*/\r
- forcedinline AudioBlock& move (size_t srcPos, size_t dstPos,\r
- size_t numElements = std::numeric_limits<size_t>::max()) noexcept\r
- {\r
- jassert (srcPos <= numSamples && dstPos <= numSamples);\r
- auto len = jmin (numSamples - srcPos, numSamples - dstPos, numElements) * sizeof (SampleType);\r
-\r
- if (len != 0)\r
- for (size_t ch = 0; ch < numChannels; ++ch)\r
- ::memmove (getChannelPointer (ch) + dstPos,\r
- getChannelPointer (ch) + srcPos, len);\r
-\r
- return *this;\r
- }\r
+ AudioBlock& move (size_t srcPos, size_t dstPos,\r
+ size_t numElements = std::numeric_limits<size_t>::max()) noexcept { moveInternal (srcPos, dstPos, numElements); return *this; }\r
+ const AudioBlock& move (size_t srcPos, size_t dstPos,\r
+ size_t numElements = std::numeric_limits<size_t>::max()) const noexcept { moveInternal (srcPos, dstPos, numElements); return *this; }\r
\r
//==============================================================================\r
- /** Return a new AudioBlock pointing to a sub-block inside the receiver. This\r
+ /** Return a new AudioBlock pointing to a sub-block inside this block. This\r
function does not copy the memory and you must ensure that the original memory\r
pointed to by the receiver remains valid through-out the life-time of the\r
returned sub-block.\r
will become the first element of the return value.\r
@param newLength The number of elements of the newly created sub-block.\r
*/\r
- inline AudioBlock getSubBlock (size_t newOffset, size_t newLength) const noexcept\r
+ AudioBlock getSubBlock (size_t newOffset, size_t newLength) const noexcept\r
{\r
jassert (newOffset < numSamples);\r
jassert (newOffset + newLength <= numSamples);\r
return AudioBlock (channels, numChannels, startSample + newOffset, newLength);\r
}\r
\r
- /** Return a new AudioBlock pointing to a sub-block inside the receiver. This\r
+ /** Return a new AudioBlock pointing to a sub-block inside this block. This\r
function does not copy the memory and you must ensure that the original memory\r
pointed to by the receiver remains valid through-out the life-time of the\r
returned sub-block.\r
\r
- @param newOffset The index of an element inside the receiver which will\r
+ @param newOffset The index of an element inside the block which will\r
will become the first element of the return value.\r
The return value will include all subsequent elements\r
of the receiver.\r
*/\r
- inline AudioBlock getSubBlock (size_t newOffset) const noexcept\r
+ AudioBlock getSubBlock (size_t newOffset) const noexcept\r
{\r
return getSubBlock (newOffset, getNumSamples() - newOffset);\r
}\r
\r
//==============================================================================\r
- /** Adds a fixed value to the receiver. */\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE add (SampleType value) noexcept\r
+ /** Adds a fixed value to the elements in this block. */\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE add (SampleType value) noexcept { addInternal (value); return *this; }\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE add (SampleType value) const noexcept { addInternal (value); return *this; }\r
+\r
+ /** Adds the elements in the src block to the elements in this block. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& add (AudioBlock<OtherSampleType> src) noexcept { addInternal (src); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& add (AudioBlock<OtherSampleType> src) const noexcept { addInternal (src); return *this; }\r
+\r
+ /** Adds a fixed value to each source value and replaces the contents of this block. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock<OtherSampleType> src, SampleType value) noexcept { replaceWithSumOfInternal (src, value); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock<OtherSampleType> src, SampleType value) const noexcept { replaceWithSumOfInternal (src, value); return *this; }\r
+\r
+ /** Adds each source1 value to the corresponding source2 value and replaces the contents of this block. */\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ AudioBlock& replaceWithSumOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithSumOfInternal (src1, src2); return *this; }\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ const AudioBlock& replaceWithSumOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithSumOfInternal (src1, src2); return *this; }\r
+\r
+ //==============================================================================\r
+ /** Subtracts a fixed value from the elements in this block. */\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE subtract (SampleType value) noexcept { subtractInternal (value); return *this; }\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE subtract (SampleType value) const noexcept { subtractInternal (value); return *this; }\r
+\r
+ /** Subtracts the source values from the elements in this block. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& subtract (AudioBlock<OtherSampleType> src) noexcept { subtractInternal (src); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& subtract (AudioBlock<OtherSampleType> src) const noexcept { subtractInternal (src); return *this; }\r
+\r
+ /** Subtracts a fixed value from each source value and replaces the contents of this block. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock<OtherSampleType> src, SampleType value) noexcept { replaceWithDifferenceOfInternal (src, value); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock<OtherSampleType> src, SampleType value) const noexcept { replaceWithDifferenceOfInternal (src, value); return *this; }\r
+\r
+ /** Subtracts each source2 value from the corresponding source1 value and replaces the contents of this block. */\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ AudioBlock& replaceWithDifferenceOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; }\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ const AudioBlock& replaceWithDifferenceOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; }\r
+\r
+ //==============================================================================\r
+ /** Multiplies the elements in this block by a fixed value. */\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (SampleType value) noexcept { multiplyByInternal (value); return *this; }\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (SampleType value) const noexcept { multiplyByInternal (value); return *this; }\r
+\r
+ /** Multiplies the elements in this block by the elements in the src block */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& multiplyBy (AudioBlock<OtherSampleType> src) noexcept { multiplyByInternal (src); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& multiplyBy (AudioBlock<OtherSampleType> src) const noexcept { multiplyByInternal (src); return *this; }\r
+\r
+ /** Replaces the elements in this block with the product of the elements in the source src block and a fixed value. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock<OtherSampleType> src, SampleType value) noexcept { replaceWithProductOfInternal (src, value); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock<OtherSampleType> src, SampleType value) const noexcept { replaceWithProductOfInternal (src, value); return *this; }\r
+\r
+ /** Replaces the elements in this block with the product of the elements in the src1 and scr2 blocks. */\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ AudioBlock& replaceWithProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithProductOfInternal (src1, src2); return *this; }\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ const AudioBlock& replaceWithProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithProductOfInternal (src1, src2); return *this; }\r
+\r
+ //==============================================================================\r
+ /** Multiplies each channels of this block by a smoothly changing value. */\r
+ template <typename SmoothingType>\r
+ AudioBlock& multiplyBy (SmoothedValue<SampleType, SmoothingType>& value) noexcept { multiplyByInternal (value); return *this; }\r
+ template <typename SmoothingType>\r
+ const AudioBlock& multiplyBy (SmoothedValue<SampleType, SmoothingType>& value) const noexcept { multiplyByInternal (value); return *this; }\r
+\r
+ /** Replaces each channel of this block with the product of the src block and a smoothed value. */\r
+ template <typename OtherSampleType, typename SmoothingType>\r
+ AudioBlock& replaceWithProductOf (AudioBlock<OtherSampleType> src, SmoothedValue<SampleType, SmoothingType>& value) noexcept { replaceWithProductOfInternal (src, value); return *this; }\r
+ template <typename OtherSampleType, typename SmoothingType>\r
+ const AudioBlock& replaceWithProductOf (AudioBlock<OtherSampleType> src, SmoothedValue<SampleType, SmoothingType>& value) const noexcept { replaceWithProductOfInternal (src, value); return *this; }\r
+\r
+ //==============================================================================\r
+ /** Multiplies each value in src by a fixed value and adds the result to this block. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock<OtherSampleType> src, SampleType factor) noexcept { addProductOfInternal (src, factor); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock<OtherSampleType> src, SampleType factor) const noexcept { addProductOfInternal (src, factor); return *this; }\r
+\r
+ /** Multiplies each value in srcA with the corresponding value in srcB and adds the result to this block. */\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ AudioBlock& addProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { addProductOfInternal (src1, src2); return *this; }\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ const AudioBlock& addProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { addProductOfInternal (src1, src2); return *this; }\r
+\r
+ //==============================================================================\r
+ /** Negates each value of this block. */\r
+ AudioBlock& negate() noexcept { negateInternal(); return *this; }\r
+ const AudioBlock& negate() const noexcept { negateInternal(); return *this; }\r
+\r
+ /** Replaces the contents of this block with the negative of the values in the src block. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& replaceWithNegativeOf (AudioBlock<OtherSampleType> src) noexcept { replaceWithNegativeOfInternal (src); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& replaceWithNegativeOf (AudioBlock<OtherSampleType> src) const noexcept { replaceWithNegativeOfInternal (src); return *this; }\r
+\r
+ /** Replaces the contents of this block with the absolute values of the src block. */\r
+ template <typename OtherSampleType>\r
+ AudioBlock& replaceWithAbsoluteValueOf (AudioBlock<OtherSampleType> src) noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; }\r
+ template <typename OtherSampleType>\r
+ const AudioBlock& replaceWithAbsoluteValueOf (AudioBlock<OtherSampleType> src) const noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; }\r
+\r
+ //==============================================================================\r
+ /** Replaces each element of this block with the minimum of the corresponding element of the source arrays. */\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ AudioBlock& replaceWithMinOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithMinOfInternal (src1, src2); return *this; }\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ const AudioBlock& replaceWithMinOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithMinOfInternal (src1, src2); return *this; }\r
+\r
+ /** Replaces each element of this block with the maximum of the corresponding element of the source arrays. */\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ AudioBlock& replaceWithMaxOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithMaxOfInternal (src1, src2); return *this; }\r
+ template <typename Src1SampleType, typename Src2SampleType>\r
+ const AudioBlock& replaceWithMaxOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithMaxOfInternal (src1, src2); return *this; }\r
+\r
+ //==============================================================================\r
+ /** Finds the minimum and maximum value of the buffer. */\r
+ Range<typename std::remove_const<NumericType>::type> findMinAndMax() const noexcept\r
+ {\r
+ if (numChannels == 0)\r
+ return {};\r
+\r
+ auto n = static_cast<int> (numSamples * sizeFactor);\r
+ auto minmax = FloatVectorOperations::findMinAndMax (getChannelPointer (0), n);\r
+\r
+ for (size_t ch = 1; ch < numChannels; ++ch)\r
+ minmax = minmax.getUnionWith (FloatVectorOperations::findMinAndMax (getChannelPointer (ch), n));\r
+\r
+ return minmax;\r
+ }\r
+\r
+ //==============================================================================\r
+ // Convenient operator wrappers.\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (SampleType value) noexcept { return add (value); }\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (SampleType value) const noexcept { return add (value); }\r
+\r
+ AudioBlock& operator+= (AudioBlock src) noexcept { return add (src); }\r
+ const AudioBlock& operator+= (AudioBlock src) const noexcept { return add (src); }\r
+\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (SampleType value) noexcept { return subtract (value); }\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (SampleType value) const noexcept { return subtract (value); }\r
+\r
+ AudioBlock& operator-= (AudioBlock src) noexcept { return subtract (src); }\r
+ const AudioBlock& operator-= (AudioBlock src) const noexcept { return subtract (src); }\r
+\r
+ AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (SampleType value) noexcept { return multiplyBy (value); }\r
+ const AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (SampleType value) const noexcept { return multiplyBy (value); }\r
+\r
+ AudioBlock& operator*= (AudioBlock src) noexcept { return multiplyBy (src); }\r
+ const AudioBlock& operator*= (AudioBlock src) const noexcept { return multiplyBy (src); }\r
+\r
+ template <typename SmoothingType>\r
+ AudioBlock& operator*= (SmoothedValue<SampleType, SmoothingType>& value) noexcept { return multiplyBy (value); }\r
+ template <typename SmoothingType>\r
+ const AudioBlock& operator*= (SmoothedValue<SampleType, SmoothingType>& value) const noexcept { return multiplyBy (value); }\r
+\r
+ //==============================================================================\r
+ // This class can only be used with floating point types\r
+ static_assert (std::is_same<std::remove_const_t<SampleType>, float>::value\r
+ || std::is_same<std::remove_const_t<SampleType>, double>::value\r
+ #if JUCE_USE_SIMD\r
+ || std::is_same<std::remove_const_t<SampleType>, SIMDRegister<float>>::value\r
+ || std::is_same<std::remove_const_t<SampleType>, SIMDRegister<double>>::value\r
+ #endif\r
+ , "AudioBlock only supports single or double precision floating point types");\r
+\r
+ //==============================================================================\r
+ /** Applies a function to each value in an input block, putting the result into an output block.\r
+ The function supplied must take a SampleType as its parameter, and return a SampleType.\r
+ The two blocks must have the same number of channels and samples.\r
+ */\r
+ template <typename Src1SampleType, typename Src2SampleType, typename FunctionType>\r
+ static void process (AudioBlock<Src1SampleType> inBlock, AudioBlock<Src2SampleType> outBlock, FunctionType&& function)\r
+ {\r
+ auto len = inBlock.getNumSamples();\r
+ auto numChans = inBlock.getNumChannels();\r
+\r
+ jassert (len == outBlock.getNumSamples());\r
+ jassert (numChans == outBlock.getNumChannels());\r
+\r
+ for (ChannelCountType c = 0; c < numChans; ++c)\r
+ {\r
+ auto* src = inBlock.getChannelPointer (c);\r
+ auto* dst = outBlock.getChannelPointer (c);\r
+\r
+ for (size_t i = 0; i < len; ++i)\r
+ dst[i] = function (src[i]);\r
+ }\r
+ }\r
+\r
+private:\r
+ //==============================================================================\r
+ void JUCE_VECTOR_CALLTYPE clearInternal() const noexcept\r
{\r
auto n = static_cast<int> (numSamples * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::add (channelPtr (ch), value, n);\r
+ FloatVectorOperations::clear (getChannelPointer (ch), n);\r
+ }\r
\r
- return *this;\r
+ void JUCE_VECTOR_CALLTYPE fillInternal (SampleType value) const noexcept\r
+ {\r
+ auto n = static_cast<int> (numSamples * sizeFactor);\r
+\r
+ for (size_t ch = 0; ch < numChannels; ++ch)\r
+ FloatVectorOperations::fill (getChannelPointer (ch), value, n);\r
+ }\r
+\r
+ template <typename OtherSampleType>\r
+ void copyFromInternal (const AudioBlock<OtherSampleType>& src) const noexcept\r
+ {\r
+ auto maxChannels = jmin (src.numChannels, numChannels);\r
+ auto n = static_cast<int> (jmin (src.numSamples, numSamples) * sizeFactor);\r
+\r
+ for (size_t ch = 0; ch < maxChannels; ++ch)\r
+ FloatVectorOperations::copy (getChannelPointer (ch), src.getChannelPointer (ch), n);\r
+ }\r
+\r
+ template <typename OtherSampleType>\r
+ void copyFromInternal (const AudioBuffer<OtherSampleType>& src, size_t srcPos, size_t dstPos, size_t numElements) const\r
+ {\r
+ auto srclen = static_cast<size_t> (src.getNumSamples()) / sizeFactor;\r
+ auto n = static_cast<int> (jmin (srclen - srcPos, numSamples - dstPos, numElements) * sizeFactor);\r
+ auto maxChannels = jmin (static_cast<size_t> (src.getNumChannels()), static_cast<size_t> (numChannels));\r
+\r
+ for (size_t ch = 0; ch < maxChannels; ++ch)\r
+ FloatVectorOperations::copy (getChannelPointer (ch) + dstPos,\r
+ src.getReadPointer (static_cast<int> (ch),\r
+ static_cast<int> (srcPos * sizeFactor)),\r
+ n);\r
+ }\r
+\r
+ void moveInternal (size_t srcPos, size_t dstPos,\r
+ size_t numElements = std::numeric_limits<size_t>::max()) const noexcept\r
+ {\r
+ jassert (srcPos <= numSamples && dstPos <= numSamples);\r
+ auto len = jmin (numSamples - srcPos, numSamples - dstPos, numElements) * sizeof (SampleType);\r
+\r
+ if (len != 0)\r
+ for (size_t ch = 0; ch < numChannels; ++ch)\r
+ ::memmove (getChannelPointer (ch) + dstPos,\r
+ getChannelPointer (ch) + srcPos, len);\r
+ }\r
+\r
+ //==============================================================================\r
+ void JUCE_VECTOR_CALLTYPE addInternal (SampleType value) const noexcept\r
+ {\r
+ auto n = static_cast<int> (numSamples * sizeFactor);\r
+\r
+ for (size_t ch = 0; ch < numChannels; ++ch)\r
+ FloatVectorOperations::add (getChannelPointer (ch), value, n);\r
}\r
\r
- /** Adds the source values to the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& add (AudioBlock<OtherSampleType> src) noexcept\r
+ void addInternal (AudioBlock<OtherSampleType> src) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::add (channelPtr (ch), src.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::add (getChannelPointer (ch), src.getChannelPointer (ch), n);\r
}\r
\r
- /** Adds a fixed value to each source value and stores it in the destination array of the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE add (AudioBlock<OtherSampleType> src, SampleType value) noexcept\r
+ void JUCE_VECTOR_CALLTYPE replaceWithSumOfInternal (AudioBlock<OtherSampleType> src, SampleType value) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::add (channelPtr (ch), src.channelPtr (ch), value, n);\r
-\r
- return *this;\r
+ FloatVectorOperations::add (getChannelPointer (ch), src.getChannelPointer (ch), value, n);\r
}\r
\r
- /** Adds each source1 value to the corresponding source2 value and stores it in the destination array of the receiver. */\r
template <typename Src1SampleType, typename Src2SampleType>\r
- forcedinline AudioBlock& add (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept\r
+ void replaceWithSumOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept\r
{\r
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::add (channelPtr (ch), src1.channelPtr (ch), src2.getChannelPointer (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::add (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n);\r
}\r
\r
- /** Subtracts a fixed value from the receiver. */\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE subtract (SampleType value) noexcept\r
+ //==============================================================================\r
+ constexpr void JUCE_VECTOR_CALLTYPE subtractInternal (SampleType value) const noexcept\r
{\r
- return add (value * static_cast<SampleType> (-1.0));\r
+ addInternal (value * static_cast<SampleType> (-1.0));\r
}\r
\r
- /** Subtracts the source values from the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& subtract (AudioBlock<OtherSampleType> src) noexcept\r
+ void subtractInternal (AudioBlock<OtherSampleType> src) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::subtract (channelPtr (ch), src.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::subtract (getChannelPointer (ch), src.getChannelPointer (ch), n);\r
}\r
\r
- /** Subtracts a fixed value from each source value and stores it in the destination array of the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE subtract (AudioBlock<OtherSampleType> src, SampleType value) noexcept\r
+ void JUCE_VECTOR_CALLTYPE replaceWithDifferenceOfInternal (AudioBlock<OtherSampleType> src, SampleType value) const noexcept\r
{\r
- return add (src, static_cast<SampleType> (-1.0) * value);\r
+ replaceWithSumOfInternal (src, static_cast<SampleType> (-1.0) * value);\r
}\r
\r
- /** Subtracts each source2 value from the corresponding source1 value and stores it in the destination array of the receiver. */\r
template <typename Src1SampleType, typename Src2SampleType>\r
- forcedinline AudioBlock& subtract (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept\r
+ void replaceWithDifferenceOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept\r
{\r
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::subtract (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::subtract (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n);\r
}\r
\r
- /** Multiplies a fixed value to the receiver. */\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE multiply (SampleType value) noexcept\r
+ //==============================================================================\r
+ void JUCE_VECTOR_CALLTYPE multiplyByInternal (SampleType value) const noexcept\r
{\r
auto n = static_cast<int> (numSamples * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::multiply (channelPtr (ch), value, n);\r
-\r
- return *this;\r
+ FloatVectorOperations::multiply (getChannelPointer (ch), value, n);\r
}\r
\r
- /** Multiplies the source values to the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& multiply (AudioBlock<OtherSampleType> src) noexcept\r
+ void multiplyByInternal (AudioBlock<OtherSampleType> src) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::multiply (channelPtr (ch), src.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::multiply (getChannelPointer (ch), src.getChannelPointer (ch), n);\r
}\r
\r
- /** Multiplies a fixed value to each source value and stores it in the destination array of the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE multiply (AudioBlock<OtherSampleType> src, SampleType value) noexcept\r
+ void JUCE_VECTOR_CALLTYPE replaceWithProductOfInternal (AudioBlock<OtherSampleType> src, SampleType value) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::multiply (channelPtr (ch), src.channelPtr (ch), value, n);\r
-\r
- return *this;\r
+ FloatVectorOperations::multiply (getChannelPointer (ch), src.getChannelPointer (ch), value, n);\r
}\r
\r
- /** Multiplies each source1 value to the corresponding source2 value and stores it in the destination array of the receiver. */\r
template <typename Src1SampleType, typename Src2SampleType>\r
- forcedinline AudioBlock& multiply (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept\r
+ void replaceWithProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept\r
{\r
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::multiply (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::multiply (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n);\r
}\r
\r
- /** Multiplies all channels of the AudioBlock by a smoothly changing value and stores them . */\r
template <typename SmoothingType>\r
- AudioBlock& multiply (SmoothedValue<SampleType, SmoothingType>& value) noexcept\r
+ void multiplyByInternal (SmoothedValue<SampleType, SmoothingType>& value) const noexcept\r
{\r
if (! value.isSmoothing())\r
{\r
- *this *= value.getTargetValue();\r
+ multiplyByInternal (value.getTargetValue());\r
}\r
else\r
{\r
const auto scaler = value.getNextValue();\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- channelPtr (ch)[i] *= scaler;\r
+ getChannelPointer (ch)[i] *= scaler;\r
}\r
}\r
-\r
- return *this;\r
}\r
\r
- /** Multiplies all channels of the source by a smoothly changing value and stores them in the receiver. */\r
template <typename OtherSampleType, typename SmoothingType>\r
- AudioBlock& multiply (AudioBlock<OtherSampleType> src, SmoothedValue<SampleType, SmoothingType>& value) noexcept\r
+ void replaceWithProductOfInternal (AudioBlock<OtherSampleType> src, SmoothedValue<SampleType, SmoothingType>& value) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
\r
if (! value.isSmoothing())\r
{\r
- multiply (src, value.getTargetValue());\r
+ replaceWithProductOfInternal (src, value.getTargetValue());\r
}\r
else\r
{\r
const auto scaler = value.getNextValue();\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- channelPtr (ch)[i] = scaler * src.getChannelPointer (ch)[i];\r
+ getChannelPointer (ch)[i] = scaler * src.getChannelPointer (ch)[i];\r
}\r
}\r
-\r
- return *this;\r
}\r
\r
- /** Multiplies each value in src with factor and adds the result to the receiver. */\r
+ //==============================================================================\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE addWithMultiply (AudioBlock<OtherSampleType> src, SampleType factor) noexcept\r
+ void JUCE_VECTOR_CALLTYPE addProductOfInternal (AudioBlock<OtherSampleType> src, SampleType factor) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::addWithMultiply (channelPtr (ch), src.channelPtr (ch), factor, n);\r
-\r
- return *this;\r
+ FloatVectorOperations::addWithMultiply (getChannelPointer (ch), src.getChannelPointer (ch), factor, n);\r
}\r
\r
- /** Multiplies each value in srcA with the corresponding value in srcB and adds the result to the receiver. */\r
template <typename Src1SampleType, typename Src2SampleType>\r
- forcedinline AudioBlock& addWithMultiply (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept\r
+ void addProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept\r
{\r
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::addWithMultiply (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::addWithMultiply (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n);\r
}\r
\r
- /** Negates each value of the receiver. */\r
- forcedinline AudioBlock& negate() noexcept\r
+ //==============================================================================\r
+ constexpr void negateInternal() const noexcept\r
{\r
- return multiply (static_cast<SampleType> (-1.0));\r
+ multiplyByInternal (static_cast<SampleType> (-1.0));\r
}\r
\r
- /** Negates each value of source and stores it in the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& replaceWithNegativeOf (AudioBlock<OtherSampleType> src) noexcept\r
+ void replaceWithNegativeOfInternal (AudioBlock<OtherSampleType> src) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::negate (channelPtr (ch), src.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::negate (getChannelPointer (ch), src.getChannelPointer (ch), n);\r
}\r
\r
- /** Takes the absolute value of each element of src and stores it inside the receiver. */\r
template <typename OtherSampleType>\r
- forcedinline AudioBlock& replaceWithAbsoluteValueOf (AudioBlock<OtherSampleType> src) noexcept\r
+ void replaceWithAbsoluteValueOfInternal (AudioBlock<OtherSampleType> src) const noexcept\r
{\r
jassert (numChannels == src.numChannels);\r
auto n = static_cast<int> (jmin (numSamples, src.numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::abs (channelPtr (ch), src.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::abs (getChannelPointer (ch), src.getChannelPointer (ch), n);\r
}\r
\r
- /** Each element of receiver will be the minimum of the corresponding element of the source arrays. */\r
+ //==============================================================================\r
template <typename Src1SampleType, typename Src2SampleType>\r
- forcedinline AudioBlock& min (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept\r
+ void replaceWithMinOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept\r
{\r
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);\r
auto n = static_cast<int> (jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::min (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::min (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n);\r
}\r
\r
- /** Each element of the receiver will be the maximum of the corresponding element of the source arrays. */\r
template <typename Src1SampleType, typename Src2SampleType>\r
- forcedinline AudioBlock& max (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept\r
+ void replaceWithMaxOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept\r
{\r
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);\r
auto n = static_cast<int> (jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor);\r
\r
for (size_t ch = 0; ch < numChannels; ++ch)\r
- FloatVectorOperations::max (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n);\r
-\r
- return *this;\r
+ FloatVectorOperations::max (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n);\r
}\r
\r
- /** Finds the minimum and maximum value of the buffer. */\r
- forcedinline Range<NumericType> findMinAndMax() const noexcept\r
- {\r
- if (numChannels == 0)\r
- return {};\r
-\r
- auto n = static_cast<int> (numSamples * sizeFactor);\r
- auto minmax = FloatVectorOperations::findMinAndMax (channelPtr (0), n);\r
-\r
- for (size_t ch = 1; ch < numChannels; ++ch)\r
- minmax = minmax.getUnionWith (FloatVectorOperations::findMinAndMax (channelPtr (ch), n));\r
-\r
- return minmax;\r
- }\r
-\r
- //==============================================================================\r
- // convenient operator wrappers\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (SampleType src) noexcept { return add (src); }\r
- forcedinline AudioBlock& operator+= (AudioBlock src) noexcept { return add (src); }\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (SampleType src) noexcept { return subtract (src); }\r
- forcedinline AudioBlock& operator-= (AudioBlock src) noexcept { return subtract (src); }\r
- forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (SampleType src) noexcept { return multiply (src); }\r
- forcedinline AudioBlock& operator*= (AudioBlock src) noexcept { return multiply (src); }\r
- template <typename SmoothingType>\r
- forcedinline AudioBlock& operator*= (SmoothedValue<SampleType, SmoothingType>& value) noexcept { return multiply (value); }\r
-\r
- //==============================================================================\r
- // This class can only be used with floating point types\r
- static_assert (std::is_same<std::remove_const_t<SampleType>, float>::value\r
- || std::is_same<std::remove_const_t<SampleType>, double>::value\r
- #if JUCE_USE_SIMD\r
- || std::is_same<std::remove_const_t<SampleType>, SIMDRegister<float>>::value\r
- || std::is_same<std::remove_const_t<SampleType>, SIMDRegister<double>>::value\r
- #endif\r
- , "AudioBlock only supports single or double precision floating point types");\r
-\r
- //==============================================================================\r
- /** Applies a function to each value in an input block, putting the result into an output block.\r
- The function supplied must take a SampleType as its parameter, and return a SampleType.\r
- The two blocks must have the same number of channels and samples.\r
- */\r
- template <typename Src1SampleType, typename Src2SampleType, typename FunctionType>\r
- static void process (AudioBlock<Src1SampleType> inBlock, AudioBlock<Src2SampleType> outBlock, FunctionType&& function)\r
- {\r
- auto len = inBlock.getNumSamples();\r
- auto numChans = inBlock.getNumChannels();\r
-\r
- jassert (len == outBlock.getNumSamples());\r
- jassert (numChans == outBlock.getNumChannels());\r
-\r
- for (ChannelCountType c = 0; c < numChans; ++c)\r
- {\r
- auto* src = inBlock.getChannelPointer (c);\r
- auto* dst = outBlock.getChannelPointer (c);\r
-\r
- for (size_t i = 0; i < len; ++i)\r
- dst[i] = function (src[i]);\r
- }\r
- }\r
-\r
-private:\r
- //==============================================================================\r
- NumericType* channelPtr (size_t ch) noexcept { return reinterpret_cast<NumericType*> (getChannelPointer (ch)); }\r
- const NumericType* channelPtr (size_t ch) const noexcept { return reinterpret_cast<const NumericType*> (getChannelPointer (ch)); }\r
-\r
//==============================================================================\r
using ChannelCountType = unsigned int;\r
\r
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+namespace juce\r
+{\r
+namespace dsp\r
+{\r
+\r
+class AudioBlockUnitTests : public UnitTest\r
+{\r
+public:\r
+ AudioBlockUnitTests()\r
+ : UnitTest ("AudioBlock", UnitTestCategories::dsp)\r
+ {}\r
+\r
+ void runTest() override\r
+ {\r
+ beginTest ("Equality");\r
+ {\r
+ expect (block == block);\r
+ expect (block != otherBlock);\r
+ }\r
+\r
+ beginTest ("Constructors");\r
+ {\r
+ expect (block == AudioBlock<float> (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) data.getNumSamples()));\r
+ expect (block == AudioBlock<float> (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) 0, (size_t) data.getNumSamples()));\r
+ expect (block == AudioBlock<float> (block));\r
+\r
+ expect (block == AudioBlock<const float> (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) data.getNumSamples()));\r
+ expect (block == AudioBlock<const float> (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) 0, (size_t) data.getNumSamples()));\r
+ expect (block == AudioBlock<const float> (block));\r
+ }\r
+\r
+ beginTest ("Swap");\r
+ {\r
+ resetBlocks();\r
+\r
+ expect (block != otherBlock);\r
+ expectEquals (block.getSample (0, 0), 1.0f);\r
+ expectEquals (block.getSample (0, 4), 5.0f);\r
+ expectEquals (otherBlock.getSample (0, 0), -1.0f);\r
+ expectEquals (otherBlock.getSample (0, 3), -4.0f);\r
+\r
+ block.swap (otherBlock);\r
+\r
+ expect (block != otherBlock);\r
+ expectEquals (otherBlock.getSample (0, 0), 1.0f);\r
+ expectEquals (otherBlock.getSample (0, 4), 5.0f);\r
+ expectEquals (block.getSample (0, 0), -1.0f);\r
+ expectEquals (block.getSample (0, 3), -4.0f);\r
+ }\r
+\r
+ beginTest ("Getters and setters");\r
+ {\r
+ resetBlocks();\r
+\r
+ expectEquals ((int) block.getNumChannels(), data.getNumChannels());\r
+ expectEquals ((int) block.getNumSamples(), data.getNumSamples());\r
+\r
+ expectEquals (block.getChannelPointer (0)[2], 3.0f);\r
+ block.getChannelPointer (0)[2] = 999.0f;\r
+ expectEquals (block.getChannelPointer (0)[2], 999.0f);\r
+\r
+ expectEquals (block.getSample (0, 4), 5.0f);\r
+ expectEquals (block.getSample (1, 4), 11.0f);\r
+\r
+ expectEquals (block.getSingleChannelBlock (1).getSample (0, 3), block.getSample (1, 3));\r
+\r
+ expectEquals (block.getSubsetChannelBlock (0, 2).getSample (1, 3), block.getSample (1, 3));\r
+ expectEquals (block.getSubsetChannelBlock (1, 1).getSample (0, 3), block.getSample (1, 3));\r
+\r
+ block.setSample (1, 1, 777.0f);\r
+ expectEquals (block.getSample (1, 1), 777.0f);\r
+\r
+ block.addSample (1, 1, 1.0f);\r
+ expectEquals (block.getSample (1, 1), 778.0f);\r
+ }\r
+\r
+ beginTest ("Copying");\r
+ {\r
+ block.clear();\r
+ expectEquals (block.getSample (0, 2), 0.0f);\r
+ expectEquals (block.getSample (1, 4), 0.0f);\r
+\r
+ block.fill (456.0f);\r
+ expectEquals (block.getSample (0, 2), 456.0f);\r
+ expectEquals (block.getSample (1, 4), 456.0f);\r
+\r
+ block.copyFrom (otherBlock);\r
+ expect (block != otherBlock);\r
+ expectEquals (block.getSample (0, 2), otherBlock.getSample (0, 2));\r
+ expectEquals (block.getSample (1, 4), otherBlock.getSample (1, 4));\r
+\r
+ resetBlocks();\r
+\r
+ AudioBuffer<float> otherBuffer ((int) block.getNumChannels(), (int) block.getNumSamples());\r
+ otherBlock.copyTo (otherBuffer);\r
+ expectEquals (otherBlock.getSample (0, 2), otherBuffer.getSample (0, 2));\r
+ expectEquals (otherBlock.getSample (1, 4), otherBuffer.getSample (1, 4));\r
+\r
+ block.copyFrom (otherBuffer);\r
+ expectEquals (block.getSample (0, 2), otherBlock.getSample (0, 2));\r
+ expectEquals (block.getSample (1, 4), otherBlock.getSample (1, 4));\r
+\r
+ float testSample1 = block.getSample (0, 2);\r
+ float testSample2 = block.getSample (1, 3);\r
+ expect (testSample1 != block.getSample (0, 4));\r
+ expect (testSample2 != block.getSample (1, 5));\r
+ block.move (0, 2);\r
+ expectEquals (block.getSample (0, 4), testSample1);\r
+ expectEquals (block.getSample (1, 5), testSample2);\r
+ }\r
+\r
+ beginTest ("Addition");\r
+ {\r
+ resetBlocks();\r
+\r
+ block.add (15.0f);\r
+ expectEquals (block.getSample (0, 4), 20.0f);\r
+ expectEquals (block.getSample (1, 4), 26.0f);\r
+\r
+ block.add (otherBlock);\r
+ expectEquals (block.getSample (0, 4), 15.0f);\r
+ expectEquals (block.getSample (1, 4), 15.0f);\r
+\r
+ block.replaceWithSumOf (otherBlock, 9.0f);\r
+ expectEquals (block.getSample (0, 4), 4.0f);\r
+ expectEquals (block.getSample (1, 4), -2.0f);\r
+\r
+ resetBlocks();\r
+\r
+ block.replaceWithSumOf (block, otherBlock);\r
+ expectEquals (block.getSample (0, 4), 0.0f);\r
+ expectEquals (block.getSample (1, 4), 0.0f);\r
+ }\r
+\r
+ beginTest ("Subtraction");\r
+ {\r
+ resetBlocks();\r
+\r
+ block.subtract (15.0f);\r
+ expectEquals (block.getSample (0, 4), -10.0f);\r
+ expectEquals (block.getSample (1, 4), -4.0f);\r
+\r
+ block.subtract (otherBlock);\r
+ expectEquals (block.getSample (0, 4), -5.0f);\r
+ expectEquals (block.getSample (1, 4), 7.0f);\r
+\r
+ block.replaceWithDifferenceOf (otherBlock, 9.0f);\r
+ expectEquals (block.getSample (0, 4), -14.0f);\r
+ expectEquals (block.getSample (1, 4), -20.0f);\r
+\r
+ resetBlocks();\r
+\r
+ block.replaceWithDifferenceOf (block, otherBlock);\r
+ expectEquals (block.getSample (0, 4), 10.0f);\r
+ expectEquals (block.getSample (1, 4), 22.0f);\r
+ }\r
+\r
+ beginTest ("Multiplication");\r
+ {\r
+ resetBlocks();\r
+\r
+ block.multiplyBy (10.0f);\r
+ expectEquals (block.getSample (0, 4), 50.0f);\r
+ expectEquals (block.getSample (1, 4), 110.0f);\r
+\r
+ block.multiplyBy (otherBlock);\r
+ expectEquals (block.getSample (0, 4), -250.0f);\r
+ expectEquals (block.getSample (1, 4), -1210.0f);\r
+\r
+ block.replaceWithProductOf (otherBlock, 3.0f);\r
+ expectEquals (block.getSample (0, 4), -15.0f);\r
+ expectEquals (block.getSample (1, 4), -33.0f);\r
+\r
+ resetBlocks();\r
+\r
+ block.replaceWithProductOf (block, otherBlock);\r
+ expectEquals (block.getSample (0, 4), -25.0f);\r
+ expectEquals (block.getSample (1, 4), -121.0f);\r
+ }\r
+\r
+ beginTest ("Smoothing");\r
+ {\r
+ block.fill (1.0f);\r
+ SmoothedValue<float> sv { 1.0f };\r
+ sv.reset (1, 4);\r
+ sv.setTargetValue (0.0f);\r
+\r
+ block.multiplyBy (sv);\r
+ expect (block.getSample (0, 2) < 1.0f);\r
+ expect (block.getSample (1, 2) < 1.0f);\r
+ expect (block.getSample (0, 2) > 0.0f);\r
+ expect (block.getSample (1, 2) > 0.0f);\r
+ expectEquals (block.getSample (0, 5), 0.0f);\r
+ expectEquals (block.getSample (1, 5), 0.0f);\r
+\r
+ sv.setCurrentAndTargetValue (-1.0f);\r
+ sv.setTargetValue (0.0f);\r
+ otherBlock.fill (-1.0f);\r
+ block.replaceWithProductOf (otherBlock, sv);\r
+ expect (block.getSample (0, 2) < 1.0f);\r
+ expect (block.getSample (1, 2) < 1.0f);\r
+ expect (block.getSample (0, 2) > 0.0f);\r
+ expect (block.getSample (1, 2) > 0.0f);\r
+ expectEquals (block.getSample (0, 5), 0.0f);\r
+ expectEquals (block.getSample (1, 5), 0.0f);\r
+ }\r
+\r
+ beginTest ("Multiply add");\r
+ {\r
+ resetBlocks();\r
+\r
+ block.addProductOf (otherBlock, -1.0f);\r
+ expectEquals (block.getSample (0, 4), 10.0f);\r
+ expectEquals (block.getSample (1, 4), 22.0f);\r
+\r
+ block.addProductOf (otherBlock, otherBlock);\r
+ expectEquals (block.getSample (0, 4), 35.0f);\r
+ expectEquals (block.getSample (1, 4), 143.0f);\r
+ }\r
+\r
+ beginTest ("Negative abs min max");\r
+ {\r
+ resetBlocks();\r
+ otherBlock.negate();\r
+\r
+ block.add (otherBlock);\r
+ expectEquals (block.getSample (0, 4), 10.0f);\r
+ expectEquals (block.getSample (1, 4), 22.0f);\r
+\r
+ block.replaceWithNegativeOf (otherBlock);\r
+ expectEquals (block.getSample (0, 4), -5.0f);\r
+ expectEquals (block.getSample (1, 4), -11.0f);\r
+\r
+ block.clear();\r
+ otherBlock.negate();\r
+ block.replaceWithAbsoluteValueOf (otherBlock);\r
+ expectEquals (block.getSample (0, 4), 5.0f);\r
+ expectEquals (block.getSample (1, 4), 11.0f);\r
+\r
+ resetBlocks();\r
+ block.replaceWithMinOf (block, otherBlock);\r
+ expectEquals (block.getSample (0, 4), -5.0f);\r
+ expectEquals (block.getSample (1, 4), -11.0f);\r
+\r
+ resetBlocks();\r
+ block.replaceWithMaxOf (block, otherBlock);\r
+ expectEquals (block.getSample (0, 4), 5.0f);\r
+ expectEquals (block.getSample (1, 4), 11.0f);\r
+\r
+ resetBlocks();\r
+ auto range = block.findMinAndMax();\r
+ expectEquals (range.getStart(), 1.0f);\r
+ expectEquals (range.getEnd(), 12.0f);\r
+ }\r
+\r
+ beginTest ("Operators");\r
+ {\r
+ resetBlocks();\r
+ block += 10.0f;\r
+ expectEquals (block.getSample (0, 4), 15.0f);\r
+ expectEquals (block.getSample (1, 4), 21.0f);\r
+ block += otherBlock;\r
+ expectEquals (block.getSample (0, 4), 10.0f);\r
+ expectEquals (block.getSample (1, 4), 10.0f);\r
+\r
+ resetBlocks();\r
+ block -= 10.0f;\r
+ expectEquals (block.getSample (0, 4), -5.0f);\r
+ expectEquals (block.getSample (1, 4), 1.0f);\r
+ block -= otherBlock;\r
+ expectEquals (block.getSample (0, 4), 0.0f);\r
+ expectEquals (block.getSample (1, 4), 12.0f);\r
+\r
+ resetBlocks();\r
+ block *= 10.0f;\r
+ expectEquals (block.getSample (0, 4), 50.0f);\r
+ expectEquals (block.getSample (1, 4), 110.0f);\r
+ block *= otherBlock;\r
+ expectEquals (block.getSample (0, 4), -250.0f);\r
+ expectEquals (block.getSample (1, 4), -1210.0f);\r
+ }\r
+\r
+ beginTest ("Process");\r
+ {\r
+ resetBlocks();\r
+ AudioBlock<float>::process (block, otherBlock, [](float x) { return x + 1.0f; });\r
+ expectEquals (otherBlock.getSample (0, 4), 6.0f);\r
+ expectEquals (otherBlock.getSample (1, 4), 12.0f);\r
+ }\r
+ }\r
+\r
+private:\r
+ AudioBuffer<float> data { 2, 6 }, otherData { 2, 6 };\r
+ AudioBlock<float> block { data }, otherBlock { otherData };\r
+\r
+ void resetBlocks()\r
+ {\r
+ auto value = 1.0f;\r
+\r
+ for (size_t c = 0; c < block.getNumChannels(); ++c)\r
+ {\r
+ for (size_t i = 0; i < block.getNumSamples(); ++i)\r
+ {\r
+ block.setSample ((int) c, (int) i, value);\r
+ value += 1.0f;\r
+ }\r
+ }\r
+\r
+ otherBlock.replaceWithNegativeOf (block);\r
+ }\r
+};\r
+\r
+static AudioBlockUnitTests audioBlockUnitTests;\r
+\r
+} // namespace dsp\r
+} // namespace juce\r
}\r
\r
if (input.getNumChannels() > 1 && currentInfo.wantsStereo == false)\r
- output.getSingleChannelBlock (1).copy (output.getSingleChannelBlock (0));\r
+ output.getSingleChannelBlock (1).copyFrom (output.getSingleChannelBlock (0));\r
}\r
\r
//==============================================================================\r
\r
if (volumeDry[0].isSmoothing())\r
{\r
- dry.copy (input);\r
+ dry.copyFrom (input);\r
\r
for (size_t channel = 0; channel < numChannels; ++channel)\r
volumeDry[channel].applyGain (dry.getChannelPointer (channel), (int) numSamples);\r
#include "containers/juce_SIMDRegister_test.cpp"\r
#endif\r
\r
+ #include "containers/juce_AudioBlock_test.cpp"\r
#include "frequency/juce_FFT_test.cpp"\r
#include "processors/juce_FIRFilter_test.cpp"\r
#endif\r
\r
ID: juce_dsp\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE DSP classes\r
description: Classes for audio buffer manipulation, digital audio processing, filtering, oversampling, fast math functions etc.\r
website: http://www.juce.com/juce\r
bias.skip (static_cast<int> (len));\r
\r
if (context.usesSeparateInputAndOutputBlocks())\r
- outBlock.copy (inBlock);\r
+ outBlock.copyFrom (inBlock);\r
\r
return;\r
}\r
gain.skip (static_cast<int> (len));\r
\r
if (context.usesSeparateInputAndOutputBlocks())\r
- outBlock.copy (inBlock);\r
+ outBlock.copyFrom (inBlock);\r
\r
return;\r
}\r
\r
if (! enabled || context.isBypassed)\r
{\r
- outputBlock.copy (inputBlock);\r
+ outputBlock.copyFrom (inputBlock);\r
return;\r
}\r
\r
OversamplingStage (size_t numChans, size_t newFactor) : numChannels (numChans), factor (newFactor) {}\r
virtual ~OversamplingStage() {}\r
\r
- //===============================================================================\r
+ //==============================================================================\r
virtual SampleType getLatencyInSamples() = 0;\r
\r
virtual void initProcessing (size_t maximumNumberOfSamplesBeforeOversampling)\r
};\r
\r
\r
-//===============================================================================\r
+//==============================================================================\r
/** Dummy oversampling stage class which simply copies and pastes the input\r
signal, which could be equivalent to a "one time" oversampling processing.\r
*/\r
\r
OversamplingDummy (size_t numChans) : ParentType (numChans, 1) {}\r
\r
- //===============================================================================\r
+ //==============================================================================\r
SampleType getLatencyInSamples() override\r
{\r
return 0;\r
jassert (outputBlock.getNumChannels() <= static_cast<size_t> (ParentType::buffer.getNumChannels()));\r
jassert (outputBlock.getNumSamples() * ParentType::factor <= static_cast<size_t> (ParentType::buffer.getNumSamples()));\r
\r
- outputBlock.copy (ParentType::getProcessedSamples (outputBlock.getNumSamples()));\r
+ outputBlock.copyFrom (ParentType::getProcessedSamples (outputBlock.getNumSamples()));\r
}\r
\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OversamplingDummy)\r
};\r
\r
-//===============================================================================\r
+//==============================================================================\r
/** Oversampling stage class performing 2 times oversampling using the Filter\r
Design FIR Equiripple method. The resulting filter is linear phase,\r
symmetric, and has every two samples but the middle one equal to zero,\r
position.resize (static_cast<int> (this->numChannels));\r
}\r
\r
- //===============================================================================\r
+ //==============================================================================\r
SampleType getLatencyInSamples() override\r
{\r
return static_cast<SampleType> (coefficientsUp.getFilterOrder() + coefficientsDown.getFilterOrder()) * 0.5f;\r
}\r
\r
private:\r
- //===============================================================================\r
+ //==============================================================================\r
dsp::FIR::Coefficients<SampleType> coefficientsUp, coefficientsDown;\r
AudioBuffer<SampleType> stateUp, stateDown, stateDown2;\r
Array<size_t> position;\r
\r
- //===============================================================================\r
+ //==============================================================================\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling2TimesEquirippleFIR)\r
};\r
\r
\r
-//===============================================================================\r
+//==============================================================================\r
/** Oversampling stage class performing 2 times oversampling using the Filter\r
Design IIR Polyphase Allpass Cascaded method. The resulting filter is minimum\r
phase, and provided with a method to get the exact resulting latency.\r
delayDown.resize (static_cast<int> (this->numChannels));\r
}\r
\r
- //===============================================================================\r
+ //==============================================================================\r
SampleType getLatencyInSamples() override\r
{\r
return latency;\r
}\r
\r
private:\r
- //===============================================================================\r
+ //==============================================================================\r
/** This function calculates the equivalent high order IIR filter of a given\r
polyphase cascaded allpass filters structure.\r
*/\r
return coeffs;\r
}\r
\r
- //===============================================================================\r
+ //==============================================================================\r
Array<SampleType> coefficientsUp, coefficientsDown;\r
SampleType latency;\r
\r
AudioBuffer<SampleType> v1Up, v1Down;\r
Array<SampleType> delayDown;\r
\r
- //===============================================================================\r
+ //==============================================================================\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling2TimesPolyphaseIIR)\r
};\r
\r
\r
-//===============================================================================\r
+//==============================================================================\r
template <typename SampleType>\r
Oversampling<SampleType>::Oversampling (size_t newNumChannels)\r
: numChannels (newNumChannels)\r
stages.clear();\r
}\r
\r
-//===============================================================================\r
+//==============================================================================\r
template <typename SampleType>\r
void Oversampling<SampleType>::addDummyOversamplingStage()\r
{\r
factorOversampling = 1u;\r
}\r
\r
-//===============================================================================\r
+//==============================================================================\r
template <typename SampleType>\r
SampleType Oversampling<SampleType>::getLatencyInSamples() noexcept\r
{\r
return factorOversampling;\r
}\r
\r
-//===============================================================================\r
+//==============================================================================\r
template <typename SampleType>\r
void Oversampling<SampleType>::initProcessing (size_t maximumNumberOfSamplesBeforeOversampling)\r
{\r
namespace dsp\r
{\r
\r
-//===============================================================================\r
+//==============================================================================\r
/**\r
A processing class performing multi-channel oversampling.\r
\r
numFilterTypes\r
};\r
\r
- //===============================================================================\r
+ //==============================================================================\r
/**\r
Constructor of the oversampling class. All the processing parameters must be\r
provided at the creation of the oversampling object.\r
/** Destructor. */\r
~Oversampling();\r
\r
- //===============================================================================\r
+ //==============================================================================\r
/** Returns the latency in samples of the whole processing. Use this information\r
in your main processor to compensate the additional latency involved with\r
the oversampling, for example with a dry / wet functionality, and to report\r
/** Returns the current oversampling factor. */\r
size_t getOversamplingFactor() noexcept;\r
\r
- //===============================================================================\r
+ //==============================================================================\r
/** Must be called before any processing, to set the buffer sizes of the internal\r
buffers of the oversampling processing.\r
*/\r
*/\r
void processSamplesDown (dsp::AudioBlock<SampleType>& outputBlock) noexcept;\r
\r
- //===============================================================================\r
+ //==============================================================================\r
/** Adds a new oversampling stage to the Oversampling class, multiplying the\r
current oversampling factor by two. This is used with the default constructor\r
to create custom oversampling chains, requiring a call to the\r
*/\r
void clearOversamplingStages();\r
\r
- //===============================================================================\r
+ //==============================================================================\r
size_t factorOversampling = 1;\r
size_t numChannels = 1;\r
\r
#endif\r
\r
private:\r
- //===============================================================================\r
+ //==============================================================================\r
OwnedArray<OversamplingStage> stages;\r
bool isReady = false;\r
\r
- //===============================================================================\r
+ //==============================================================================\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling)\r
};\r
\r
\r
jassert (inputBlock.getNumSamples() == numSamples);\r
\r
- outputBlock.copy (inputBlock);\r
+ outputBlock.copyFrom (inputBlock);\r
\r
if (! enabled || context.isBypassed)\r
return;\r
if (context.isBypassed)\r
{\r
if (context.usesSeparateInputAndOutputBlocks())\r
- context.getOutputBlock().copy (context.getInputBlock());\r
+ context.getOutputBlock().copyFrom (context.getInputBlock());\r
}\r
else\r
{\r
\r
ID: juce_events\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE message and event handling classes\r
description: Classes for running an application's main event loop and sending/receiving messages, timers, etc.\r
website: http://www.juce.com/juce\r
virtual void memoryWarningReceived() { jassertfalse; }\r
\r
//==============================================================================\r
- /** Override this method to be informed when the back button is pressed on a device.\r
+ /** This will be called when the back button on a device is pressed. The return value\r
+ should be used to indicate whether the back button event has been handled by\r
+ the application, for example if you want to implement custom navigation instead\r
+ of the standard behaviour on Android.\r
+\r
This is currently only implemented on Android devices.\r
+\r
+ @returns true if the event has been handled, or false if the default OS\r
+ behaviour should happen\r
*/\r
- virtual void backButtonPressed() {}\r
+ virtual bool backButtonPressed() { return false; }\r
\r
//==============================================================================\r
/** Signals that the main message loop should stop and the application should terminate.\r
return nullptr;\r
}\r
\r
-void MessageManager::callAsync (std::function<void()> fn)\r
+bool MessageManager::callAsync (std::function<void()> fn)\r
{\r
struct AsyncCallInvoker : public MessageBase\r
{\r
- AsyncCallInvoker (std::function<void()> f) : callback (std::move (f)) { post(); }\r
+ AsyncCallInvoker (std::function<void()> f) : callback (std::move (f)) {}\r
void messageCallback() override { callback(); }\r
std::function<void()> callback;\r
};\r
\r
- new AsyncCallInvoker (std::move (fn));\r
+ return (new AsyncCallInvoker (std::move (fn)))->post();\r
}\r
\r
//==============================================================================\r
#endif\r
\r
//==============================================================================\r
- /** Asynchronously invokes a function or C++11 lambda on the message thread. */\r
- static void callAsync (std::function<void()> functionToCall);\r
+ /** Asynchronously invokes a function or C++11 lambda on the message thread.\r
+\r
+ @returns true if the message was successfully posted to the message queue,\r
+ or false otherwise.\r
+ */\r
+ static bool callAsync (std::function<void()> functionToCall);\r
\r
/** Calls a function using the message-thread.\r
\r
@param fd the file descriptor to be monitored\r
@param readCallback a callback that will be called when the file descriptor has\r
data to read. The file descriptor will be passed as an argument\r
+ @param eventMask a bit mask specifying the events you are interested in for the\r
+ file descriptor. The possible values for this are defined in\r
+ <poll.h>\r
*/\r
- void registerFdCallback (int fd, std::function<void(int)> readCallback);\r
+ void registerFdCallback (int fd, std::function<void(int)> readCallback, short eventMask = 1 /*POLLIN*/);\r
\r
/** Unregisters a previously registered file descriptor.\r
\r
==============================================================================\r
*/\r
\r
-#include <poll.h>\r
-\r
namespace juce\r
{\r
\r
LinuxEventLoop::registerFdCallback (getReadHandle(),\r
[this] (int fd)\r
{\r
- if (auto msg = popNextMessage (fd))\r
+ while (auto msg = popNextMessage (fd))\r
{\r
JUCE_TRY\r
{\r
}\r
\r
//==============================================================================\r
- JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (InternalMessageQueue)\r
+ JUCE_DECLARE_SINGLETON (InternalMessageQueue, false)\r
\r
private:\r
CriticalSection lock;\r
fdReadCallbacks.reserve (8);\r
}\r
\r
- void registerFdCallback (int fd, std::function<void(int)>&& cb)\r
+ void registerFdCallback (int fd, std::function<void(int)>&& cb, short eventMask)\r
{\r
const ScopedLock sl (lock);\r
\r
fdReadCallbacks.push_back ({ fd, std::move (cb) });\r
- pfds.push_back ({ fd, POLLIN, 0 });\r
+ pfds.push_back ({ fd, eventMask, 0 });\r
}\r
\r
void unregisterFdCallback (int fd)\r
}\r
\r
//==============================================================================\r
- JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (InternalRunLoop)\r
+ JUCE_DECLARE_SINGLETON (InternalRunLoop, false)\r
\r
private:\r
CriticalSection lock;\r
}\r
\r
//==============================================================================\r
-void LinuxEventLoop::registerFdCallback (int fd, std::function<void(int)> readCallback)\r
+void LinuxEventLoop::registerFdCallback (int fd, std::function<void(int)> readCallback, short eventMask)\r
{\r
if (auto* runLoop = InternalRunLoop::getInstanceWithoutCreating())\r
- runLoop->registerFdCallback (fd, std::move (readCallback));\r
+ runLoop->registerFdCallback (fd, std::move (readCallback), eventMask);\r
}\r
\r
void LinuxEventLoop::unregisterFdCallback (int fd)\r
/** Tries to draw a text string inside a given space.\r
\r
This does its best to make the given text readable within the specified rectangle,\r
- so it useful for labelling things.\r
+ so it's useful for labelling things.\r
\r
If the text is too big, it'll be squashed horizontally or broken over multiple lines\r
if the maximumLinesToUse value allows this. If the text just won't fit into the space,\r
/** Tries to draw a text string inside a given space.\r
\r
This does its best to make the given text readable within the specified rectangle,\r
- so it useful for labelling things.\r
+ so it's useful for labelling things.\r
\r
If the text is too big, it'll be squashed horizontally or broken over multiple lines\r
if the maximumLinesToUse value allows this. If the text just won't fit into the space,\r
/** Tries to fit some text within a given space.\r
\r
This does its best to make the given text readable within the specified rectangle,\r
- so it useful for labelling things.\r
+ so it's useful for labelling things.\r
\r
If the text is too big, it'll be squashed horizontally or broken over multiple lines\r
if the maximumLinesToUse value allows this. If the text just won't fit into the space,\r
}\r
}\r
\r
-//==============================================================================\r
-#if JUCE_UNIT_TESTS\r
-\r
-struct TextLayoutTests : public UnitTest\r
-{\r
- TextLayoutTests()\r
- : UnitTest ("Text Layout", UnitTestCategories::text)\r
- {}\r
-\r
- static TextLayout createLayout (StringRef text, float width)\r
- {\r
- Font fontToUse (12.0f);\r
-\r
- AttributedString string (text);\r
- string.setFont (std::move (fontToUse));\r
-\r
- TextLayout layout;\r
- layout.createLayout (std::move (string), width);\r
-\r
- return layout;\r
- }\r
-\r
- void testLineBreaks (const String& line, float width, const StringArray& expected)\r
- {\r
- const auto layout = createLayout (line, width);\r
-\r
- beginTest ("A line is split into expected pieces");\r
- {\r
- expectEquals (layout.getNumLines(), expected.size());\r
-\r
- const auto limit = jmin (layout.getNumLines(), expected.size());\r
-\r
- for (int i = 0; i != limit; ++i)\r
- expectEquals (substring (line, layout.getLine (i).stringRange), expected[i]);\r
- }\r
- }\r
-\r
- void runTest() override\r
- {\r
- const String shortLine ("hello world");\r
- testLineBreaks (shortLine, 1.0e7f, { shortLine });\r
-\r
- testLineBreaks ("this line should be split",\r
- 60.0f,\r
- { "this line ",\r
- "should be ",\r
- "split" });\r
-\r
- testLineBreaks ("these\nlines \nhave\n weird \n spacing ",\r
- 80.0f,\r
- { "these\n",\r
- "lines \n",\r
- "have\n",\r
- " weird \n",\r
- " spacing " });\r
- }\r
-};\r
-\r
-static TextLayoutTests textLayoutTests;\r
-\r
-#endif\r
-\r
} // namespace juce\r
destRegion.clear();\r
\r
if (! rect.isEmpty())\r
- for (auto& r : rects)\r
+ for (auto r : rects)\r
if (rect.intersectRectangle (r))\r
destRegion.rects.add (r);\r
\r
The coordinate you provide here isn't checked, so it's the caller's responsibility to make\r
sure it's not out-of-range.\r
*/\r
- inline uint8* getLinePointer (int y) const noexcept { return data + y * lineStride; }\r
+ inline uint8* getLinePointer (int y) const noexcept { return data + (size_t) y * (size_t) lineStride; }\r
\r
/** Returns a pointer to a pixel in the image.\r
The coordinates you give here are not checked, so it's the caller's responsibility to make sure they're\r
not out-of-range.\r
*/\r
- inline uint8* getPixelPointer (int x, int y) const noexcept { return data + y * lineStride + x * pixelStride; }\r
+ inline uint8* getPixelPointer (int x, int y) const noexcept { return data + (size_t) y * (size_t) lineStride + (size_t) x * (size_t) pixelStride; }\r
\r
/** Returns the colour of a given pixel.\r
For performance reasons, this won't do any bounds-checking on the coordinates, so it's the caller's\r
\r
ID: juce_graphics\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE graphics classes\r
description: Classes for 2D vector graphics, image loading/saving, font handling, etc.\r
website: http://www.juce.com/juce\r
\r
auto cgTransformToJuceTransform = [](CGAffineTransform& t) -> AffineTransform\r
{\r
- return { (float) t.a, (float) t.b, (float) t.tx,\r
- (float) t.c, (float) t.d, (float) t.ty };\r
+ return { (float) t.a, (float) t.c, (float) t.tx,\r
+ (float) t.b, (float) t.d, (float) t.ty };\r
};\r
\r
state->fontTransform = cgTransformToJuceTransform (fontTransform);\r
{\r
if (state->fontRef != nullptr && state->fillType.isColour())\r
{\r
- if (transform.isOnlyTranslation())\r
+ if (transform.isOnlyTranslation() && state->fontTransform.isOnlyTranslation())\r
{\r
auto t = transform.followedBy (state->inverseFontTransform);\r
\r
if (! availableStyles.contains (style))\r
{\r
if (font.isItalic()) // Fake-up an italic font if there isn't a real one.\r
- requiredTransform = CGAffineTransformMake (1.0f, 0, 0.25f, 1.0f, 0, 0);\r
+ requiredTransform = CGAffineTransformMake (1.0f, 0, 0.1f, 1.0f, 0, 0);\r
\r
return availableStyles[0];\r
}\r
\r
ID: juce_gui_basics\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE GUI core classes\r
description: Basic user-interface components and related classes.\r
website: http://www.juce.com/juce\r
\r
struct Grid::SizeCalculation\r
{\r
- static float getTotalAbsoluteSize (const juce::Array<Grid::TrackInfo>& tracks, Px gapSize) noexcept\r
+ static float getTotalAbsoluteSize (const Array<Grid::TrackInfo>& tracks, Px gapSize) noexcept\r
{\r
float totalCellSize = 0.0f;\r
\r
for (const auto& trackInfo : tracks)\r
- if (! trackInfo.isFraction || trackInfo.hasKeyword)\r
- totalCellSize += trackInfo.size;\r
+ if (! trackInfo.isFractional() || trackInfo.isAuto())\r
+ totalCellSize += trackInfo.getSize();\r
\r
float totalGap = tracks.size() > 1 ? static_cast<float> ((tracks.size() - 1) * gapSize.pixels)\r
: 0.0f;\r
return totalCellSize + totalGap;\r
}\r
\r
- static float getRelativeUnitSize (float size, float totalAbsolute, const juce::Array<Grid::TrackInfo>& tracks) noexcept\r
+ static float getRelativeUnitSize (float size, float totalAbsolute, const Array<Grid::TrackInfo>& tracks) noexcept\r
{\r
- const float totalRelative = juce::jlimit (0.0f, size, size - totalAbsolute);\r
+ const float totalRelative = jlimit (0.0f, size, size - totalAbsolute);\r
float factorsSum = 0.0f;\r
\r
for (const auto& trackInfo : tracks)\r
- if (trackInfo.isFraction)\r
- factorsSum += trackInfo.size;\r
+ if (trackInfo.isFractional())\r
+ factorsSum += trackInfo.getSize();\r
\r
jassert (factorsSum != 0.0f);\r
return totalRelative / factorsSum;\r
}\r
\r
//==============================================================================\r
- static float getTotalAbsoluteHeight (const juce::Array<Grid::TrackInfo>& rowTracks, Px rowGap)\r
+ static float getTotalAbsoluteHeight (const Array<Grid::TrackInfo>& rowTracks, Px rowGap)\r
{\r
return getTotalAbsoluteSize (rowTracks, rowGap);\r
}\r
\r
- static float getTotalAbsoluteWidth (const juce::Array<Grid::TrackInfo>& columnTracks, Px columnGap)\r
+ static float getTotalAbsoluteWidth (const Array<Grid::TrackInfo>& columnTracks, Px columnGap)\r
{\r
return getTotalAbsoluteSize (columnTracks, columnGap);\r
}\r
\r
- static float getRelativeWidthUnit (float gridWidth, Px columnGap, const juce::Array<Grid::TrackInfo>& columnTracks)\r
+ static float getRelativeWidthUnit (float gridWidth, Px columnGap, const Array<Grid::TrackInfo>& columnTracks)\r
{\r
return getRelativeUnitSize (gridWidth, getTotalAbsoluteWidth (columnTracks, columnGap), columnTracks);\r
}\r
\r
- static float getRelativeHeightUnit (float gridHeight, Px rowGap, const juce::Array<Grid::TrackInfo>& rowTracks)\r
+ static float getRelativeHeightUnit (float gridHeight, Px rowGap, const Array<Grid::TrackInfo>& rowTracks)\r
{\r
return getRelativeUnitSize (gridHeight, getTotalAbsoluteHeight (rowTracks, rowGap), rowTracks);\r
}\r
\r
//==============================================================================\r
- static bool hasAnyFractions (const juce::Array<Grid::TrackInfo>& tracks)\r
+ static bool hasAnyFractions (const Array<Grid::TrackInfo>& tracks)\r
{\r
for (auto& t : tracks)\r
- if (t.isFraction)\r
+ if (t.isFractional())\r
return true;\r
\r
return false;\r
\r
void computeSizes (float gridWidth, float gridHeight,\r
Px columnGapToUse, Px rowGapToUse,\r
- const juce::Array<Grid::TrackInfo>& columnTracks,\r
- const juce::Array<Grid::TrackInfo>& rowTracks)\r
+ const Array<Grid::TrackInfo>& columnTracks,\r
+ const Array<Grid::TrackInfo>& rowTracks)\r
{\r
if (hasAnyFractions (columnTracks))\r
relativeWidthUnit = getRelativeWidthUnit (gridWidth, columnGapToUse, columnTracks);\r
//==============================================================================\r
struct LineRange { int start, end; };\r
struct LineArea { LineRange column, row; };\r
- struct LineInfo { juce::StringArray lineNames; };\r
+ struct LineInfo { StringArray lineNames; };\r
\r
struct NamedArea\r
{\r
- juce::String name;\r
+ String name;\r
LineArea lines;\r
};\r
\r
//==============================================================================\r
- static juce::Array<LineInfo> getArrayOfLinesFromTracks (const juce::Array<Grid::TrackInfo>& tracks)\r
+ static Array<LineInfo> getArrayOfLinesFromTracks (const Array<Grid::TrackInfo>& tracks)\r
{\r
// fill line info array\r
- juce::Array<LineInfo> lines;\r
+ Array<LineInfo> lines;\r
\r
for (int i = 1; i <= tracks.size(); ++i)\r
{\r
if (i == 1) // start line\r
{\r
LineInfo li;\r
- li.lineNames.add (currentTrack.startLineName);\r
+ li.lineNames.add (currentTrack.getStartLineName());\r
lines.add (li);\r
}\r
\r
const auto& prevTrack = tracks.getReference (i - 2);\r
\r
LineInfo li;\r
- li.lineNames.add (prevTrack.endLineName);\r
- li.lineNames.add (currentTrack.startLineName);\r
+ li.lineNames.add (prevTrack.getEndLineName());\r
+ li.lineNames.add (currentTrack.getStartLineName());\r
\r
lines.add (li);\r
}\r
if (i == tracks.size()) // end line\r
{\r
LineInfo li;\r
- li.lineNames.add (currentTrack.endLineName);\r
+ li.lineNames.add (currentTrack.getEndLineName());\r
lines.add (li);\r
}\r
}\r
\r
//==============================================================================\r
static int deduceAbsoluteLineNumberFromLineName (GridItem::Property prop,\r
- const juce::Array<Grid::TrackInfo>& tracks)\r
+ const Array<Grid::TrackInfo>& tracks)\r
{\r
jassert (prop.hasAbsolute());\r
\r
{\r
for (const auto& name : lines.getReference (i).lineNames)\r
{\r
- if (prop.name == name)\r
+ if (prop.getName() == name)\r
{\r
++count;\r
break;\r
}\r
}\r
\r
- if (count == prop.number)\r
+ if (count == prop.getNumber())\r
return i + 1;\r
}\r
\r
}\r
\r
static int deduceAbsoluteLineNumber (GridItem::Property prop,\r
- const juce::Array<Grid::TrackInfo>& tracks)\r
+ const Array<Grid::TrackInfo>& tracks)\r
{\r
jassert (prop.hasAbsolute());\r
\r
if (prop.hasName())\r
return deduceAbsoluteLineNumberFromLineName (prop, tracks);\r
\r
- return prop.number > 0 ? prop.number : tracks.size() + 2 + prop.number;\r
+ return prop.getNumber() > 0 ? prop.getNumber() : tracks.size() + 2 + prop.getNumber();\r
}\r
\r
static int deduceAbsoluteLineNumberFromNamedSpan (int startLineNumber,\r
GridItem::Property propertyWithSpan,\r
- const juce::Array<Grid::TrackInfo>& tracks)\r
+ const Array<Grid::TrackInfo>& tracks)\r
{\r
jassert (propertyWithSpan.hasSpan());\r
\r
{\r
for (const auto& name : lines.getReference (i).lineNames)\r
{\r
- if (propertyWithSpan.name == name)\r
+ if (propertyWithSpan.getName() == name)\r
{\r
++count;\r
break;\r
}\r
}\r
\r
- if (count == propertyWithSpan.number)\r
+ if (count == propertyWithSpan.getNumber())\r
return i + 1;\r
}\r
\r
\r
static int deduceAbsoluteLineNumberBasedOnSpan (int startLineNumber,\r
GridItem::Property propertyWithSpan,\r
- const juce::Array<Grid::TrackInfo>& tracks)\r
+ const Array<Grid::TrackInfo>& tracks)\r
{\r
jassert (propertyWithSpan.hasSpan());\r
\r
if (propertyWithSpan.hasName())\r
return deduceAbsoluteLineNumberFromNamedSpan (startLineNumber, propertyWithSpan, tracks);\r
\r
- return startLineNumber + propertyWithSpan.number;\r
+ return startLineNumber + propertyWithSpan.getNumber();\r
}\r
\r
//==============================================================================\r
- static LineRange deduceLineRange (GridItem::StartAndEndProperty prop, const juce::Array<Grid::TrackInfo>& tracks)\r
+ static LineRange deduceLineRange (GridItem::StartAndEndProperty prop, const Array<Grid::TrackInfo>& tracks)\r
{\r
LineRange s;\r
\r
\r
static LineArea deduceLineArea (const GridItem& item,\r
const Grid& grid,\r
- const std::map<juce::String, LineArea>& namedAreas)\r
+ const std::map<String, LineArea>& namedAreas)\r
{\r
if (item.area.isNotEmpty() && ! grid.templateAreas.isEmpty())\r
{\r
}\r
\r
//==============================================================================\r
- static juce::Array<juce::StringArray> parseAreasProperty (const juce::StringArray& areasStrings)\r
+ static Array<StringArray> parseAreasProperty (const StringArray& areasStrings)\r
{\r
- juce::Array<juce::StringArray> strings;\r
+ Array<StringArray> strings;\r
\r
for (const auto& areaString : areasStrings)\r
- strings.add (juce::StringArray::fromTokens (areaString, false));\r
+ strings.add (StringArray::fromTokens (areaString, false));\r
\r
if (strings.size() > 0)\r
{\r
return strings;\r
}\r
\r
- static NamedArea findArea (juce::Array<juce::StringArray>& stringsArrays)\r
+ static NamedArea findArea (Array<StringArray>& stringsArrays)\r
{\r
NamedArea area;\r
\r
}\r
\r
//==============================================================================\r
- static std::map<juce::String, LineArea> deduceNamedAreas (const juce::StringArray& areasStrings)\r
+ static std::map<String, LineArea> deduceNamedAreas (const StringArray& areasStrings)\r
{\r
auto stringsArrays = parseAreasProperty (areasStrings);\r
\r
- std::map<juce::String, LineArea> areas;\r
+ std::map<String, LineArea> areas;\r
\r
for (auto area = findArea (stringsArrays); area.name.isNotEmpty(); area = findArea (stringsArrays))\r
{\r
}\r
\r
//==============================================================================\r
- static float getCoord (int trackNumber, float relativeUnit, Px gap, const juce::Array<Grid::TrackInfo>& tracks)\r
+ static float getCoord (int trackNumber, float relativeUnit, Px gap, const Array<Grid::TrackInfo>& tracks)\r
{\r
float c = 0;\r
\r
for (const auto* it = tracks.begin(); it != tracks.begin() + trackNumber - 1; ++it)\r
- c += (it->isFraction ? it->size * relativeUnit : it->size) + static_cast<float> (gap.pixels);\r
+ c += it->getAbsoluteSize (relativeUnit) + static_cast<float> (gap.pixels);\r
\r
return c;\r
}\r
\r
- static juce::Rectangle<float> getCellBounds (int columnNumber, int rowNumber,\r
- const juce::Array<Grid::TrackInfo>& columnTracks,\r
- const juce::Array<Grid::TrackInfo>& rowTracks,\r
+ static Rectangle<float> getCellBounds (int columnNumber, int rowNumber,\r
+ const Array<Grid::TrackInfo>& columnTracks,\r
+ const Array<Grid::TrackInfo>& rowTracks,\r
Grid::SizeCalculation calculation,\r
Px columnGap, Px rowGap)\r
{\r
const auto y = getCoord (rowNumber, calculation.relativeHeightUnit, rowGap, rowTracks);\r
\r
const auto& columnTrackInfo = columnTracks.getReference (columnNumber - 1);\r
- const float width = columnTrackInfo.isFraction ? columnTrackInfo.size * calculation.relativeWidthUnit\r
- : columnTrackInfo.size;\r
+ const float width = columnTrackInfo.getAbsoluteSize (calculation.relativeWidthUnit);\r
\r
const auto& rowTrackInfo = rowTracks.getReference (rowNumber - 1);\r
- const float height = rowTrackInfo.isFraction ? rowTrackInfo.size * calculation.relativeHeightUnit\r
- : rowTrackInfo.size;\r
+ const float height = rowTrackInfo.getAbsoluteSize (calculation.relativeHeightUnit);\r
\r
return { x, y, width, height };\r
}\r
\r
- static juce::Rectangle<float> alignCell (juce::Rectangle<float> area,\r
+ static Rectangle<float> alignCell (Rectangle<float> area,\r
int columnNumber, int rowNumber,\r
int numberOfColumns, int numberOfRows,\r
Grid::SizeCalculation calculation,\r
return area;\r
}\r
\r
- static juce::Rectangle<float> getAreaBounds (int columnLineNumberStart, int columnLineNumberEnd,\r
+ static Rectangle<float> getAreaBounds (int columnLineNumberStart, int columnLineNumberEnd,\r
int rowLineNumberStart, int rowLineNumberEnd,\r
- const juce::Array<Grid::TrackInfo>& columnTracks,\r
- const juce::Array<Grid::TrackInfo>& rowTracks,\r
+ const Array<Grid::TrackInfo>& columnTracks,\r
+ const Array<Grid::TrackInfo>& rowTracks,\r
Grid::SizeCalculation calculation,\r
Grid::AlignContent alignContent,\r
Grid::JustifyContent justifyContent,\r
//==============================================================================\r
struct Grid::AutoPlacement\r
{\r
- using ItemPlacementArray = juce::Array<std::pair<GridItem*, Grid::PlacementHelpers::LineArea>>;\r
+ using ItemPlacementArray = Array<std::pair<GridItem*, Grid::PlacementHelpers::LineArea>>;\r
\r
//==============================================================================\r
struct OccupancyPlane\r
static int getSpanFromAuto (GridItem::StartAndEndProperty prop)\r
{\r
if (prop.end.hasSpan())\r
- return prop.end.number;\r
+ return prop.end.getNumber();\r
\r
if (prop.start.hasSpan())\r
- return prop.start.number;\r
+ return prop.start.getNumber();\r
\r
return 1;\r
}\r
{\r
const auto namedAreas = Grid::PlacementHelpers::deduceNamedAreas (grid.templateAreas);\r
\r
- OccupancyPlane plane (juce::jmax (grid.templateColumns.size() + 1, 2),\r
- juce::jmax (grid.templateRows.size() + 1, 2),\r
+ OccupancyPlane plane (jmax (grid.templateColumns.size() + 1, 2),\r
+ jmax (grid.templateRows.size() + 1, 2),\r
isColumnAutoFlow (grid.autoFlow));\r
\r
ItemPlacementArray itemPlacementArray;\r
- juce::Array<GridItem*> sortedItems;\r
+ Array<GridItem*> sortedItems;\r
\r
for (auto& item : grid.items)\r
sortedItems.add (&item);\r
return { columnEndLine, rowEndLine };\r
}\r
\r
- static std::pair<juce::Array<TrackInfo>, juce::Array<TrackInfo>> createImplicitTracks (const Grid& grid,\r
+ static std::pair<Array<TrackInfo>, Array<TrackInfo>> createImplicitTracks (const Grid& grid,\r
const ItemPlacementArray& items)\r
{\r
const auto columnAndRowLineEnds = getHighestEndLinesNumbers (items);\r
\r
- juce::Array<TrackInfo> implicitColumnTracks, implicitRowTracks;\r
+ Array<TrackInfo> implicitColumnTracks, implicitRowTracks;\r
\r
for (int i = grid.templateColumns.size() + 1; i < columnAndRowLineEnds.first; i++)\r
implicitColumnTracks.add (grid.autoColumns);\r
}\r
\r
//==============================================================================\r
- static void applySizeForAutoTracks (juce::Array<Grid::TrackInfo>& columns,\r
- juce::Array<Grid::TrackInfo>& rows,\r
+ static void applySizeForAutoTracks (Array<Grid::TrackInfo>& columns,\r
+ Array<Grid::TrackInfo>& rows,\r
const ItemPlacementArray& itemPlacementArray)\r
{\r
auto isSpan = [](Grid::PlacementHelpers::LineRange r) -> bool { return std::abs (r.end - r.start) > 1; };\r
};\r
\r
for (int i = 0; i < rows.size(); i++)\r
- if (rows.getReference (i).hasKeyword)\r
+ if (rows.getReference (i).isAuto())\r
rows.getReference (i).size = getHighestItemOnRow (i + 1, itemPlacementArray);\r
\r
for (int i = 0; i < columns.size(); i++)\r
- if (columns.getReference (i).hasKeyword)\r
+ if (columns.getReference (i).isAuto())\r
columns.getReference (i).size = getHighestItemOnColumn (i + 1, itemPlacementArray);\r
}\r
};\r
//==============================================================================\r
struct Grid::BoxAlignment\r
{\r
- static juce::Rectangle<float> alignItem (const GridItem& item,\r
+ static Rectangle<float> alignItem (const GridItem& item,\r
const Grid& grid,\r
- juce::Rectangle<float> area)\r
+ Rectangle<float> area)\r
{\r
// if item align is auto, inherit value from grid\r
Grid::AlignItems alignType = Grid::AlignItems::start;\r
justifyType = static_cast<Grid::JustifyItems> (item.justifySelf);\r
\r
// subtract margin from area\r
- area = juce::BorderSize<float> (item.margin.top, item.margin.left, item.margin.bottom, item.margin.right)\r
+ area = BorderSize<float> (item.margin.top, item.margin.left, item.margin.bottom, item.margin.right)\r
.subtractedFrom (area);\r
\r
// align and justify\r
auto r = area;\r
\r
- if (item.width != (float) GridItem::notAssigned)\r
- r.setWidth (item.width);\r
-\r
- if (item.height != (float) GridItem::notAssigned)\r
- r.setHeight (item.height);\r
+ if (item.width != (float) GridItem::notAssigned) r.setWidth (item.width);\r
+ if (item.height != (float) GridItem::notAssigned) r.setHeight (item.height);\r
+ if (item.maxWidth != (float) GridItem::notAssigned) r.setWidth (jmin (item.maxWidth, r.getWidth()));\r
+ if (item.minWidth > 0.0f) r.setWidth (jmax (item.minWidth, r.getWidth()));\r
+ if (item.maxHeight != (float) GridItem::notAssigned) r.setHeight (jmin (item.maxHeight, r.getHeight()));\r
+ if (item.minHeight > 0.0f) r.setHeight (jmax (item.minHeight, r.getHeight()));\r
\r
if (alignType == Grid::AlignItems::start && justifyType == Grid::JustifyItems::start)\r
return r;\r
\r
- if (alignType == Grid::AlignItems::end)\r
- r.setY (r.getY() + (area.getHeight() - r.getHeight()));\r
-\r
- if (justifyType == Grid::JustifyItems::end)\r
- r.setX (r.getX() + (area.getWidth() - r.getWidth()));\r
-\r
- if (alignType == Grid::AlignItems::center)\r
- r.setCentre (r.getCentreX(), area.getCentreY());\r
-\r
- if (justifyType == Grid::JustifyItems::center)\r
- r.setCentre (area.getCentreX(), r.getCentreY());\r
+ if (alignType == Grid::AlignItems::end) r.setY (r.getY() + (area.getHeight() - r.getHeight()));\r
+ if (justifyType == Grid::JustifyItems::end) r.setX (r.getX() + (area.getWidth() - r.getWidth()));\r
+ if (alignType == Grid::AlignItems::center) r.setCentre (r.getCentreX(), area.getCentreY());\r
+ if (justifyType == Grid::JustifyItems::center) r.setCentre (area.getCentreX(), r.getCentreY());\r
\r
return r;\r
}\r
\r
Grid::TrackInfo::TrackInfo (Fr fractionOfFreeSpace) noexcept : size ((float)fractionOfFreeSpace.fraction), isFraction (true) {}\r
\r
-Grid::TrackInfo::TrackInfo (Px sizeInPixels, const juce::String& endLineNameToUse) noexcept : Grid::TrackInfo (sizeInPixels)\r
+Grid::TrackInfo::TrackInfo (Px sizeInPixels, const String& endLineNameToUse) noexcept : Grid::TrackInfo (sizeInPixels)\r
{\r
endLineName = endLineNameToUse;\r
}\r
\r
-Grid::TrackInfo::TrackInfo (Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept : Grid::TrackInfo (fractionOfFreeSpace)\r
+Grid::TrackInfo::TrackInfo (Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept : Grid::TrackInfo (fractionOfFreeSpace)\r
{\r
endLineName = endLineNameToUse;\r
}\r
\r
-Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels) noexcept : Grid::TrackInfo (sizeInPixels)\r
+Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Px sizeInPixels) noexcept : Grid::TrackInfo (sizeInPixels)\r
{\r
startLineName = startLineNameToUse;\r
}\r
\r
-Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept : Grid::TrackInfo (fractionOfFreeSpace)\r
+Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept : Grid::TrackInfo (fractionOfFreeSpace)\r
{\r
startLineName = startLineNameToUse;\r
}\r
\r
-Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels, const juce::String& endLineNameToUse) noexcept\r
+Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Px sizeInPixels, const String& endLineNameToUse) noexcept\r
: Grid::TrackInfo (startLineNameToUse, sizeInPixels)\r
{\r
endLineName = endLineNameToUse;\r
}\r
\r
-Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept\r
+Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept\r
: Grid::TrackInfo (startLineNameToUse, fractionOfFreeSpace)\r
{\r
endLineName = endLineNameToUse;\r
}\r
\r
+float Grid::TrackInfo::getAbsoluteSize (float relativeFractionalUnit) const\r
+{\r
+ if (isFractional())\r
+ return size * relativeFractionalUnit;\r
+ else\r
+ return size;\r
+}\r
+\r
//==============================================================================\r
Grid::Grid() noexcept {}\r
Grid::~Grid() noexcept {}\r
\r
//==============================================================================\r
-void Grid::performLayout (juce::Rectangle<int> targetArea)\r
+void Grid::performLayout (Rectangle<int> targetArea)\r
{\r
const auto itemsAndAreas = Grid::AutoPlacement().deduceAllItems (*this);\r
\r
{\r
/** Creates a track with auto dimension. */\r
TrackInfo() noexcept;\r
- /** */\r
+\r
TrackInfo (Px sizeInPixels) noexcept;\r
- /** */\r
TrackInfo (Fr fractionOfFreeSpace) noexcept;\r
\r
- /** */\r
- TrackInfo (Px sizeInPixels, const juce::String& endLineNameToUse) noexcept;\r
- /** */\r
- TrackInfo (Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept;\r
+ TrackInfo (Px sizeInPixels, const String& endLineNameToUse) noexcept;\r
+ TrackInfo (Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept;\r
+\r
+ TrackInfo (const String& startLineNameToUse, Px sizeInPixels) noexcept;\r
+ TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept;\r
+\r
+ TrackInfo (const String& startLineNameToUse, Px sizeInPixels, const String& endLineNameToUse) noexcept;\r
+ TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept;\r
\r
- /** */\r
- TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels) noexcept;\r
- /** */\r
- TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept;\r
+ bool isAuto() const noexcept { return hasKeyword; }\r
+ bool isFractional() const noexcept { return isFraction; }\r
+ bool isPixels() const noexcept { return ! isFraction; }\r
+ const String& getStartLineName() const noexcept { return startLineName; }\r
+ const String& getEndLineName() const noexcept { return endLineName; }\r
\r
- /** */\r
- TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels, const juce::String& endLineNameToUse) noexcept;\r
- /** */\r
- TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept;\r
+ /** Get the track's size - which might mean an absolute pixels value or a fractional ratio. */\r
+ float getSize() const noexcept { return size; }\r
\r
private:\r
friend class Grid;\r
- friend class GridItem;\r
+ float getAbsoluteSize (float relativeFractionalUnit) const;\r
\r
float size = 0; // Either a fraction or an absolute size in pixels\r
bool isFraction = false;\r
bool hasKeyword = false;\r
\r
- juce::String startLineName, endLineName;\r
+ String startLineName, endLineName;\r
};\r
\r
//==============================================================================\r
\r
//==============================================================================\r
/** The set of column tracks to lay out. */\r
- juce::Array<TrackInfo> templateColumns;\r
+ Array<TrackInfo> templateColumns;\r
\r
/** The set of row tracks to lay out. */\r
- juce::Array<TrackInfo> templateRows;\r
+ Array<TrackInfo> templateRows;\r
\r
/** Template areas */\r
- juce::StringArray templateAreas;\r
+ StringArray templateAreas;\r
\r
/** The row track for auto dimension. */\r
TrackInfo autoRows;\r
\r
//==============================================================================\r
/** The set of items to lay-out. */\r
- juce::Array<GridItem> items;\r
+ Array<GridItem> items;\r
\r
//==============================================================================\r
/** Lays-out the grid's items within the given rectangle. */\r
- void performLayout (juce::Rectangle<int>);\r
+ void performLayout (Rectangle<int>);\r
\r
//==============================================================================\r
/** Returns the number of columns. */\r
jassert (keyword == GridItem::Keyword::autoValue);\r
}\r
\r
-GridItem::Property::Property (const char* lineNameToUse) noexcept : GridItem::Property (juce::String (lineNameToUse))\r
+GridItem::Property::Property (const char* lineNameToUse) noexcept : GridItem::Property (String (lineNameToUse))\r
{\r
}\r
\r
-GridItem::Property::Property (const juce::String& lineNameToUse) noexcept : name (lineNameToUse), number (1)\r
+GridItem::Property::Property (const String& lineNameToUse) noexcept : name (lineNameToUse), number (1)\r
{\r
}\r
\r
{\r
}\r
\r
-GridItem::Property::Property (int numberToUse, const juce::String& lineNameToUse) noexcept\r
+GridItem::Property::Property (int numberToUse, const String& lineNameToUse) noexcept\r
: name (lineNameToUse), number (numberToUse)\r
{\r
}\r
GridItem::GridItem() noexcept {}\r
GridItem::~GridItem() noexcept {}\r
\r
-GridItem::GridItem (juce::Component& componentToUse) noexcept : associatedComponent (&componentToUse) {}\r
-GridItem::GridItem (juce::Component* componentToUse) noexcept : associatedComponent (componentToUse) {}\r
+GridItem::GridItem (Component& componentToUse) noexcept : associatedComponent (&componentToUse) {}\r
+GridItem::GridItem (Component* componentToUse) noexcept : associatedComponent (componentToUse) {}\r
\r
void GridItem::setArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd)\r
{\r
row.start = rowStart;\r
}\r
\r
-void GridItem::setArea (const juce::String& areaName)\r
+void GridItem::setArea (const String& areaName)\r
{\r
area = areaName;\r
}\r
return gi;\r
}\r
\r
-GridItem GridItem::withArea (const juce::String& areaName) const noexcept\r
+GridItem GridItem::withArea (const String& areaName) const noexcept\r
{\r
auto gi = *this;\r
gi.setArea (areaName);\r
jassert (numberToUse > 0);\r
}\r
\r
- explicit Span (int numberToUse, const juce::String& nameToUse) : Span (numberToUse)\r
+ explicit Span (int numberToUse, const String& nameToUse) : Span (numberToUse)\r
{\r
/* Name must not be empty */\r
jassert (nameToUse.isNotEmpty());\r
name = nameToUse;\r
}\r
\r
- explicit Span (const juce::String& nameToUse) : name (nameToUse)\r
+ explicit Span (const String& nameToUse) : name (nameToUse)\r
{\r
/* Name must not be empty */\r
jassert (nameToUse.isNotEmpty());\r
}\r
\r
int number = 1;\r
- juce::String name;\r
+ String name;\r
};\r
\r
//==============================================================================\r
/** Represents a property. */\r
struct Property\r
{\r
- /** */\r
Property() noexcept;\r
\r
- /** */\r
Property (Keyword keyword) noexcept;\r
\r
- /** */\r
Property (const char* lineNameToUse) noexcept;\r
\r
- /** */\r
- Property (const juce::String& lineNameToUse) noexcept;\r
+ Property (const String& lineNameToUse) noexcept;\r
\r
- /** */\r
Property (int numberToUse) noexcept;\r
\r
- /** */\r
- Property (int numberToUse, const juce::String& lineNameToUse) noexcept;\r
+ Property (int numberToUse, const String& lineNameToUse) noexcept;\r
\r
- /** */\r
Property (Span spanToUse) noexcept;\r
\r
- private:\r
- bool hasSpan() const noexcept { return isSpan && ! isAuto; }\r
- bool hasAbsolute() const noexcept { return ! (isSpan || isAuto); }\r
- bool hasAuto() const noexcept { return isAuto; }\r
- bool hasName() const noexcept { return name.isNotEmpty(); }\r
-\r
- friend class Grid;\r
+ bool hasSpan() const noexcept { return isSpan && ! isAuto; }\r
+ bool hasAbsolute() const noexcept { return ! (isSpan || isAuto); }\r
+ bool hasAuto() const noexcept { return isAuto; }\r
+ bool hasName() const noexcept { return name.isNotEmpty(); }\r
+ const String& getName() const noexcept { return name; }\r
+ int getNumber() const noexcept { return number; }\r
\r
- juce::String name;\r
+ private:\r
+ String name;\r
int number = 1; /** Either an absolute line number or number of lines to span across. */\r
bool isSpan = false;\r
bool isAuto = false;\r
/** Creates an item with default parameters. */\r
GridItem() noexcept;\r
/** Creates an item with a given Component to use. */\r
- GridItem (juce::Component& componentToUse) noexcept;\r
+ GridItem (Component& componentToUse) noexcept;\r
/** Creates an item with a given Component to use. */\r
- GridItem (juce::Component* componentToUse) noexcept;\r
+ GridItem (Component* componentToUse) noexcept;\r
\r
/** Destructor. */\r
~GridItem() noexcept;\r
\r
//==============================================================================\r
/** If this is non-null, it represents a Component whose bounds are controlled by this item. */\r
- juce::Component* associatedComponent = nullptr;\r
+ Component* associatedComponent = nullptr;\r
\r
//==============================================================================\r
/** Determines the order used to lay out items in their grid container. */\r
StartAndEndProperty row = { Keyword::autoValue, Keyword::autoValue };\r
\r
/** */\r
- juce::String area;\r
+ String area;\r
\r
//==============================================================================\r
enum\r
};\r
\r
/* TODO: move all of this into a common class that is shared with the FlexItem */\r
- float width = notAssigned;\r
- float minWidth = 0;\r
+ float width = notAssigned;\r
+ float minWidth = 0.0f;\r
float maxWidth = notAssigned;\r
\r
- float height = notAssigned;\r
- float minHeight = 0;\r
+ float height = notAssigned;\r
+ float minHeight = 0.0f;\r
float maxHeight = notAssigned;\r
\r
/** Represents a margin. */\r
Margin margin;\r
\r
/** The item's current bounds. */\r
- juce::Rectangle<float> currentBounds;\r
+ Rectangle<float> currentBounds;\r
\r
/** Short-hand */\r
void setArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd);\r
void setArea (Property rowStart, Property columnStart);\r
\r
/** Short-hand */\r
- void setArea (const juce::String& areaName);\r
+ void setArea (const String& areaName);\r
\r
/** Short-hand */\r
GridItem withArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd) const noexcept;\r
GridItem withArea (Property rowStart, Property columnStart) const noexcept;\r
\r
/** Short-hand */\r
- GridItem withArea (const juce::String& areaName) const noexcept;\r
+ GridItem withArea (const String& areaName) const noexcept;\r
\r
/** Returns a copy of this object with a new row property. */\r
GridItem withRow (StartAndEndProperty row) const noexcept;\r
}\r
}\r
\r
-//==========================================================================\r
+//==============================================================================\r
void SidePanel::lookAndFeelChanged()\r
{\r
auto& lf = getLookAndFeel();\r
titleTextColour = 0x100f002,\r
shadowBaseColour = 0x100f003,\r
dismissButtonNormalColour = 0x100f004,\r
- dismissButtonOverColour = 0x100f004,\r
- dismissButtonDownColour = 0x100f005\r
+ dismissButtonOverColour = 0x100f005,\r
+ dismissButtonDownColour = 0x100f006\r
};\r
\r
//==============================================================================\r
std::function<void(bool)> onPanelShowHide;\r
\r
private:\r
- //==========================================================================\r
+ //==============================================================================\r
Component* parent = nullptr;\r
OptionalScopedPointer<Component> contentComponent;\r
OptionalScopedPointer<Component> titleBarComponent;\r
\r
bool shouldShowDismissButton = true;\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void lookAndFeelChanged() override;\r
void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;\r
\r
customComp = *new HeaderItemComponent (item.text);\r
\r
if (customComp != nullptr)\r
+ {\r
+ setItem (*customComp, &item);\r
addAndMakeVisible (*customComp);\r
+ }\r
\r
parent.addAndMakeVisible (this);\r
\r
\r
~ItemComponent() override\r
{\r
+ if (customComp != nullptr)\r
+ setItem (*customComp, nullptr);\r
+\r
removeChildComponent (customComp.get());\r
}\r
\r
void PopupMenu::addSectionHeader (String title)\r
{\r
Item i (std::move (title));\r
+ i.itemID = 0;\r
i.isSectionHeader = true;\r
addItem (std::move (i));\r
}\r
lookAndFeel = newLookAndFeel;\r
}\r
\r
+void PopupMenu::setItem (CustomComponent& c, const Item* itemToUse)\r
+{\r
+ c.item = itemToUse;\r
+ c.repaint();\r
+}\r
+\r
//==============================================================================\r
PopupMenu::CustomComponent::CustomComponent (bool autoTrigger)\r
: triggeredAutomatically (autoTrigger)\r
*/\r
bool isItemHighlighted() const noexcept { return isHighlighted; }\r
\r
+ /** Returns a pointer to the Item that holds this custom component, if this\r
+ component is currently held by an Item.\r
+ You can query the Item for information that you might want to use\r
+ in your paint() method, such as the item's enabled and ticked states.\r
+ */\r
+ const PopupMenu::Item* getItem() const noexcept { return item; }\r
+\r
/** @internal */\r
bool isTriggeredAutomatically() const noexcept { return triggeredAutomatically; }\r
/** @internal */\r
private:\r
//==============================================================================\r
bool isHighlighted = false, triggeredAutomatically;\r
+ const PopupMenu::Item* item = nullptr;\r
+\r
+ friend PopupMenu;\r
\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomComponent)\r
};\r
Component* createWindow (const Options&, ApplicationCommandManager**) const;\r
int showWithOptionalCallback (const Options&, ModalComponentManager::Callback*, bool);\r
\r
+ static void setItem (CustomComponent&, const Item*);\r
+\r
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE\r
// These methods have new implementations now - see its new definition\r
int drawPopupMenuItem (Graphics&, int, int, bool, bool, bool, bool, bool, const String&, const String&, Image*, const Colour*) { return 0; }\r
// This byte-code is generated from native/javacore/app/com/roli/juce/JuceSharingContentProvider.java with min sdk version 16\r
// See juce_core/native/java/README.txt on how to generate this byte-code.\r
static const uint8 javaJuceSharingContentProvider[] =\r
-{31,139,8,8,143,106,229,91,0,3,74,117,99,101,83,104,97,114,105,110,103,67,111,110,116,101,110,116,80,114,111,118,105,100,\r
-101,114,46,100,101,120,0,149,151,93,108,20,85,20,199,207,157,153,157,253,236,178,91,170,20,145,178,229,83,80,216,242,165,\r
-96,5,11,45,72,183,91,139,161,52,218,190,56,221,157,148,129,221,153,101,102,118,133,23,2,106,162,209,196,24,125,64,19,73,\r
-48,33,106,140,15,36,26,227,131,49,152,24,163,241,65,77,148,248,160,209,152,152,24,193,68,227,131,6,37,241,127,63,118,219,\r
-173,197,232,194,111,238,185,231,156,123,238,185,231,222,153,206,148,237,19,137,190,173,219,105,239,208,216,231,67,47,106,\r
-177,200,154,39,135,207,172,189,226,63,113,230,173,189,99,175,63,244,123,185,131,168,70,68,39,38,182,117,146,250,157,79,\r
-17,141,146,212,223,4,46,48,34,110,252,3,109,4,237,103,26,209,82,222,71,171,163,189,132,203,80,156,40,103,16,125,111,18,\r
-253,4,126,6,191,129,107,224,58,232,137,18,245,130,53,96,3,216,2,14,131,6,120,25,188,11,190,1,191,128,100,140,104,19,112,\r
-192,235,224,50,184,6,110,193,28,187,192,3,192,6,117,240,52,120,6,60,15,206,130,115,224,101,240,10,120,3,188,9,222,6,159,\r
-128,175,192,183,224,42,136,38,136,214,129,33,48,5,60,240,8,56,5,206,130,87,193,69,240,54,120,31,124,12,62,5,95,130,31,\r
-192,21,240,43,248,19,24,73,162,197,96,57,88,5,242,224,78,176,27,12,131,7,65,9,56,224,56,56,9,78,129,199,192,83,0,101,37,\r
-148,142,16,138,208,37,148,159,176,45,148,6,139,64,6,100,73,238,193,98,208,165,246,229,102,176,4,116,147,220,143,91,193,\r
-106,176,134,228,190,240,223,195,168,189,166,228,10,228,152,154,235,4,100,148,65,236,231,105,165,71,233,233,89,200,248,47,\r
-108,252,23,83,50,247,143,170,60,94,48,229,92,205,3,179,92,201,231,249,62,43,249,53,200,43,148,124,17,242,42,37,191,11,\r
-121,165,146,63,130,220,171,228,47,32,231,148,252,181,41,215,177,120,78,14,93,42,135,4,170,181,85,212,42,69,247,137,122,\r
-201,126,82,245,83,168,214,157,196,215,28,19,99,13,172,176,143,248,154,22,137,190,9,253,58,17,51,45,250,9,81,105,222,74,\r
-125,2,255,214,171,120,36,218,36,109,16,109,156,238,17,241,101,220,20,42,113,187,104,53,186,67,180,58,109,20,45,163,77,\r
-202,190,89,180,81,218,34,90,131,182,171,252,250,213,184,93,162,53,105,183,26,191,71,237,253,1,177,231,49,149,151,172,185,\r
-169,106,193,247,171,15,157,109,50,61,113,94,178,170,70,77,251,0,236,35,202,158,82,118,109,142,253,32,236,211,202,206,245,\r
-157,144,187,83,179,114,111,74,158,201,13,41,238,31,17,250,231,146,114,142,41,198,168,150,211,104,128,38,53,126,66,117,\r
-120,242,179,118,46,41,207,137,151,209,225,127,8,91,89,235,139,146,198,210,34,119,83,248,92,104,197,208,97,53,104,32,50,\r
-169,105,136,17,129,149,231,117,49,41,215,121,8,241,107,227,113,210,54,167,17,139,137,92,222,73,202,181,214,50,60,183,149,\r
-168,79,45,195,207,253,84,198,16,59,25,17,167,154,232,189,164,90,7,246,155,199,229,249,125,152,148,117,24,239,53,104,57,\r
-171,245,165,104,139,145,162,30,150,197,222,247,176,117,34,183,152,152,39,78,186,170,212,103,173,56,89,68,150,119,211,229,\r
-57,58,77,100,133,103,86,83,151,153,157,239,251,121,243,117,252,203,124,166,26,115,37,41,239,233,241,45,24,163,241,49,131,\r
-145,20,237,128,159,155,225,51,165,88,143,150,101,157,184,222,118,189,3,215,117,76,222,227,89,17,167,19,126,188,202,140,\r
-174,183,205,221,48,121,5,111,60,119,68,172,33,158,154,173,89,206,160,182,223,29,243,250,59,230,245,121,55,138,168,89,220,\r
-161,186,144,179,226,94,213,148,28,17,109,151,208,102,91,122,93,84,47,218,58,151,89,209,231,232,170,205,170,216,252,126,\r
-202,42,61,151,155,177,179,202,175,139,204,123,28,215,9,119,19,27,38,99,184,88,44,82,132,95,139,196,10,180,162,80,47,217,\r
-135,142,88,190,227,206,12,122,110,104,187,225,65,223,107,56,101,219,223,116,212,106,88,196,138,164,193,85,231,254,102,81,\r
-252,168,183,104,185,101,223,115,202,249,146,28,146,159,55,180,159,86,220,200,101,194,170,212,237,160,159,214,255,195,193,\r
-183,131,252,158,32,176,195,253,78,197,30,178,131,146,239,212,66,15,177,150,182,92,203,86,104,77,91,129,157,31,172,251,\r
-129,215,54,77,203,52,106,133,190,115,162,233,144,109,57,184,118,152,63,236,59,115,195,121,65,158,207,53,54,29,216,126,\r
-131,103,221,59,215,116,208,242,75,118,101,126,50,59,139,37,175,154,247,189,138,147,63,138,210,229,111,92,191,213,77,161,\r
-153,203,189,255,127,104,123,122,27,254,115,128,126,90,89,44,91,149,134,115,44,111,185,174,23,90,161,227,185,249,125,110,\r
-169,226,5,220,187,98,5,216,131,158,5,124,134,93,23,25,75,123,239,2,246,81,187,58,173,28,248,54,118,22,249,41,201,87,44,\r
-119,38,63,54,125,212,46,133,237,186,67,33,207,174,159,210,237,197,160,174,133,86,72,108,130,244,137,97,156,184,137,2,25,\r
-19,5,33,225,236,77,20,113,112,39,138,5,28,92,126,29,38,54,73,139,167,22,152,37,105,149,74,118,16,236,175,88,51,1,69,248,\r
-98,109,74,150,188,74,189,234,222,111,85,237,128,150,170,195,198,171,214,204,101,144,187,149,169,167,205,52,55,173,125,13,\r
-168,105,89,155,253,62,59,196,164,182,85,29,63,89,67,220,155,218,140,99,53,219,229,1,168,179,77,253,64,221,246,79,146,89,\r
-182,43,118,104,83,196,22,97,151,204,216,225,66,39,141,210,51,237,83,68,209,231,18,25,71,188,32,164,56,191,142,123,135,\r
-177,66,211,113,145,104,72,70,197,43,29,35,163,106,5,199,40,93,117,170,54,119,71,212,16,149,53,170,94,25,67,93,84,129,98,\r
-158,59,136,184,200,33,234,185,114,113,29,30,82,110,221,124,240,104,174,192,168,89,225,17,74,212,124,143,239,45,14,0,69,\r
-142,203,101,224,118,173,87,144,71,128,229,72,75,71,75,220,227,163,254,113,212,54,28,243,203,124,246,240,136,19,144,201,\r
-175,171,251,200,172,215,202,124,118,189,238,59,252,82,161,72,131,63,21,200,20,77,64,155,244,3,219,215,71,211,27,119,109,\r
-164,187,40,154,222,53,73,203,140,3,219,7,118,72,213,42,173,111,32,154,158,196,147,24,38,178,244,194,208,190,104,154,30,\r
-99,90,97,39,20,14,205,176,2,250,227,90,97,20,205,16,156,168,170,21,238,22,166,134,20,138,58,254,116,108,156,26,193,147,\r
-119,36,50,178,103,104,223,126,97,157,50,10,163,34,150,214,193,70,186,83,90,90,91,107,100,239,94,114,75,83,88,166,45,98,\r
-35,183,106,221,137,238,36,105,26,195,159,238,103,115,145,211,167,141,75,49,237,81,141,76,246,93,140,171,53,174,142,157,\r
-57,109,60,30,103,80,39,216,133,56,49,35,110,104,73,232,46,9,93,147,69,236,199,56,99,127,129,139,9,198,62,0,95,129,171,\r
-224,124,146,177,31,193,75,41,249,110,75,234,89,222,108,155,223,30,252,57,223,252,254,208,105,246,27,196,160,217,239,16,\r
-222,54,191,69,76,154,253,30,209,51,82,230,127,207,88,78,190,75,15,64,54,115,82,207,223,161,88,70,190,103,139,119,228,156,\r
-156,151,127,191,232,202,159,191,243,24,57,57,31,127,47,34,53,86,188,123,101,100,174,252,91,233,111,138,244,241,33,100,13,\r
-0,0};\r
+{100,101,120,10,48,51,53,0,66,68,79,209,68,153,2,8,5,37,136,73,129,38,235,114,135,129,180,66,79,170,89,247,100,13,0,0,112,0,0,\r
+0,120,86,52,18,0,0,0,0,0,0,0,0,160,12,0,0,77,0,0,0,112,0,0,0,21,0,0,0,164,1,0,0,18,0,0,0,248,1,0,0,5,0,0,0,208,2,0,0,25,0,0,0,\r
+248,2,0,0,3,0,0,0,192,3,0,0,68,9,0,0,32,4,0,0,226,6,0,0,234,6,0,0,237,6,0,0,243,6,0,0,250,6,0,0,253,6,0,0,30,7,0,0,33,7,0,0,37,\r
+7,0,0,42,7,0,0,50,7,0,0,85,7,0,0,118,7,0,0,161,7,0,0,188,7,0,0,221,7,0,0,240,7,0,0,11,8,0,0,46,8,0,0,105,8,0,0,170,8,0,0,214,\r
+8,0,0,250,8,0,0,26,9,0,0,61,9,0,0,81,9,0,0,101,9,0,0,117,9,0,0,139,9,0,0,142,9,0,0,147,9,0,0,151,9,0,0,157,9,0,0,161,9,0,0,166,\r
+9,0,0,172,9,0,0,179,9,0,0,182,9,0,0,203,9,0,0,216,9,0,0,223,9,0,0,236,9,0,0,7,10,0,0,39,10,0,0,68,10,0,0,91,10,0,0,111,10,0,\r
+0,119,10,0,0,126,10,0,0,151,10,0,0,167,10,0,0,176,10,0,0,182,10,0,0,193,10,0,0,201,10,0,0,207,10,0,0,213,10,0,0,229,10,0,0,235,\r
+10,0,0,241,10,0,0,251,10,0,0,4,11,0,0,19,11,0,0,29,11,0,0,35,11,0,0,47,11,0,0,54,11,0,0,62,11,0,0,73,11,0,0,88,11,0,0,99,11,\r
+0,0,105,11,0,0,113,11,0,0,121,11,0,0,126,11,0,0,131,11,0,0,138,11,0,0,1,0,0,0,4,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,\r
+0,0,0,15,0,0,0,16,0,0,0,17,0,0,0,18,0,0,0,19,0,0,0,20,0,0,0,21,0,0,0,22,0,0,0,23,0,0,0,24,0,0,0,25,0,0,0,28,0,0,0,36,0,0,0,37,\r
+0,0,0,3,0,0,0,0,0,0,0,96,6,0,0,2,0,0,0,0,0,0,0,108,6,0,0,8,0,0,0,4,0,0,0,120,6,0,0,9,0,0,0,5,0,0,0,128,6,0,0,8,0,0,0,7,0,0,0,\r
+144,6,0,0,6,0,0,0,9,0,0,0,0,0,0,0,8,0,0,0,9,0,0,0,120,6,0,0,7,0,0,0,17,0,0,0,152,6,0,0,28,0,0,0,18,0,0,0,0,0,0,0,29,0,0,0,18,\r
+0,0,0,160,6,0,0,30,0,0,0,18,0,0,0,168,6,0,0,31,0,0,0,18,0,0,0,176,6,0,0,35,0,0,0,18,0,0,0,188,6,0,0,34,0,0,0,18,0,0,0,200,6,\r
+0,0,33,0,0,0,18,0,0,0,212,6,0,0,32,0,0,0,18,0,0,0,220,6,0,0,36,0,0,0,19,0,0,0,0,0,0,0,8,0,0,0,20,0,0,0,120,6,0,0,10,0,1,0,51,0,\r
+0,0,10,0,12,0,71,0,0,0,11,0,1,0,51,0,0,0,11,0,12,0,71,0,0,0,12,0,16,0,54,0,0,0,2,0,8,0,0,0,0,0,4,0,5,0,48,0,0,0,6,0,15,0,0,0,\r
+0,0,6,0,8,0,39,0,0,0,8,0,14,0,0,0,0,0,10,0,13,0,0,0,0,0,10,0,8,0,39,0,0,0,10,0,10,0,41,0,0,0,11,0,12,0,0,0,0,0,11,0,11,0,42,0,\r
+0,0,11,0,9,0,60,0,0,0,12,0,8,0,0,0,0,0,12,0,17,0,43,0,0,0,12,0,2,0,44,0,0,0,12,0,3,0,45,0,0,0,12,0,1,0,46,0,0,0,12,0,17,0,49,0,\r
+0,0,12,0,7,0,50,0,0,0,12,0,4,0,53,0,0,0,12,0,16,0,59,0,0,0,12,0,2,0,61,0,0,0,12,0,6,0,62,0,0,0,12,0,3,0,65,0,0,0,12,0,0,0,72,\r
+0,0,0,16,0,8,0,0,0,0,0,10,0,0,0,17,0,0,0,6,0,0,0,0,0,0,0,5,0,0,0,48,6,0,0,52,12,0,0,0,0,0,0,11,0,0,0,17,0,0,0,8,0,0,0,0,0,0,0,\r
+5,0,0,0,64,6,0,0,75,12,0,0,0,0,0,0,12,0,0,0,17,0,0,0,2,0,0,0,0,0,0,0,5,0,0,0,80,6,0,0,98,12,0,0,0,0,0,0,2,0,0,0,18,12,0,0,24,\r
+12,0,0,2,0,0,0,18,12,0,0,33,12,0,0,1,0,0,0,42,12,0,0,5,0,5,0,2,0,0,0,146,11,0,0,8,0,0,0,91,1,1,0,112,32,2,0,64,0,90,2,0,0,14,\r
+0,3,0,1,0,3,0,0,0,157,11,0,0,9,0,0,0,111,16,3,0,2,0,83,32,0,0,112,48,7,0,2,1,14,0,0,0,6,0,6,0,3,0,0,0,164,11,0,0,8,0,0,0,91,1,\r
+3,0,112,48,4,0,64,5,90,2,2,0,14,0,5,0,3,0,5,0,0,0,176,11,0,0,6,0,0,0,83,32,2,0,112,84,9,0,2,49,14,0,2,0,1,0,1,0,0,0,184,11,0,\r
+0,11,0,0,0,112,16,0,0,1,0,34,0,16,0,112,16,24,0,0,0,91,16,4,0,14,0,0,0,5,0,4,0,0,0,0,0,190,11,0,0,2,0,0,0,18,0,15,0,5,0,3,0,3,\r
+0,1,0,198,11,0,0,12,0,0,0,84,33,4,0,29,1,112,48,12,0,50,4,12,0,30,1,17,0,13,0,30,1,39,0,3,0,0,0,8,0,1,0,1,0,9,0,3,0,2,0,0,0,0,\r
+0,208,11,0,0,2,0,0,0,18,0,17,0,4,0,3,0,0,0,0,0,214,11,0,0,2,0,0,0,18,0,17,0,2,0,1,0,0,0,0,0,221,11,0,0,2,0,0,0,18,16,15,0,5,\r
+0,3,0,3,0,1,0,226,11,0,0,12,0,0,0,84,33,4,0,29,1,112,48,13,0,50,4,12,0,30,1,17,0,13,0,30,1,39,0,3,0,0,0,8,0,1,0,1,0,9,0,6,0,3,\r
+0,3,0,1,0,235,11,0,0,21,0,0,0,84,50,4,0,29,2,112,48,13,0,67,5,12,0,56,0,8,0,110,16,1,0,0,0,12,1,30,2,17,1,18,1,30,2,40,253,13,\r
+1,30,2,39,1,0,0,3,0,0,0,17,0,1,0,1,0,18,0,8,0,6,0,6,0,1,0,253,11,0,0,12,0,0,0,84,33,4,0,29,1,118,6,14,0,2,0,12,0,30,1,17,0,13,\r
+0,30,1,39,0,3,0,0,0,8,0,1,0,1,0,9,0,6,0,5,0,0,0,0,0,9,12,0,0,2,0,0,0,18,0,15,0,32,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44,4,0,0,0,0,\r
+0,0,0,0,0,0,0,0,0,0,56,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,7,0,3,0,17,0,20,0,3,0,0,0,7,0,17,0,20,0,0,0,2,0,0,0,7,0,17,0,5,0,\r
+0,0,7,0,20,0,17,0,20,0,17,0,0,0,2,0,0,0,7,0,3,0,1,0,0,0,7,0,0,0,2,0,0,0,0,0,17,0,1,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,17,0,0,0,4,\r
+0,0,0,12,0,1,0,17,0,0,0,3,0,0,0,12,0,1,0,20,0,0,0,2,0,0,0,17,0,0,0,1,0,0,0,20,0,6,60,105,110,105,116,62,0,1,73,0,4,73,76,76,76,\r
+0,5,73,76,76,76,76,0,1,74,0,31,74,117,99,101,83,104,97,114,105,110,103,67,111,110,116,101,110,116,80,114,111,118,105,100,101,\r
+114,46,106,97,118,97,0,1,76,0,2,76,76,0,3,76,76,76,0,6,76,76,76,76,76,76,0,33,76,97,110,100,114,111,105,100,47,99,111,110,116,\r
+101,110,116,47,67,111,110,116,101,110,116,80,114,111,118,105,100,101,114,59,0,31,76,97,110,100,114,111,105,100,47,99,111,110,\r
+116,101,110,116,47,67,111,110,116,101,110,116,86,97,108,117,101,115,59,0,41,76,97,110,100,114,111,105,100,47,99,111,110,116,\r
+101,110,116,47,114,101,115,47,65,115,115,101,116,70,105,108,101,68,101,115,99,114,105,112,116,111,114,59,0,25,76,97,110,100,114,\r
+111,105,100,47,100,97,116,97,98,97,115,101,47,67,117,114,115,111,114,59,0,31,76,97,110,100,114,111,105,100,47,100,97,116,97,98,\r
+97,115,101,47,77,97,116,114,105,120,67,117,114,115,111,114,59,0,17,76,97,110,100,114,111,105,100,47,110,101,116,47,85,114,105,\r
+59,0,25,76,97,110,100,114,111,105,100,47,111,115,47,70,105,108,101,79,98,115,101,114,118,101,114,59,0,33,76,97,110,100,114,111,\r
+105,100,47,111,115,47,80,97,114,99,101,108,70,105,108,101,68,101,115,99,114,105,112,116,111,114,59,0,57,76,99,111,109,47,114,\r
+111,108,105,47,106,117,99,101,47,74,117,99,101,83,104,97,114,105,110,103,67,111,110,116,101,110,116,80,114,111,118,105,100,101,\r
+114,36,80,114,111,118,105,100,101,114,67,117,114,115,111,114,59,0,63,76,99,111,109,47,114,111,108,105,47,106,117,99,101,47,\r
+74,117,99,101,83,104,97,114,105,110,103,67,111,110,116,101,110,116,80,114,111,118,105,100,101,114,36,80,114,111,118,105,100,101,\r
+114,70,105,108,101,79,98,115,101,114,118,101,114,59,0,42,76,99,111,109,47,114,111,108,105,47,106,117,99,101,47,74,117,99,101,\r
+83,104,97,114,105,110,103,67,111,110,116,101,110,116,80,114,111,118,105,100,101,114,59,0,34,76,100,97,108,118,105,107,47,97,\r
+110,110,111,116,97,116,105,111,110,47,69,110,99,108,111,115,105,110,103,67,108,97,115,115,59,0,30,76,100,97,108,118,105,107,47,\r
+97,110,110,111,116,97,116,105,111,110,47,73,110,110,101,114,67,108,97,115,115,59,0,33,76,100,97,108,118,105,107,47,97,110,110,\r
+111,116,97,116,105,111,110,47,77,101,109,98,101,114,67,108,97,115,115,101,115,59,0,18,76,106,97,118,97,47,108,97,110,103,47,\r
+79,98,106,101,99,116,59,0,18,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,0,14,80,114,111,118,105,100,101,\r
+114,67,117,114,115,111,114,0,20,80,114,111,118,105,100,101,114,70,105,108,101,79,98,115,101,114,118,101,114,0,1,86,0,3,86,73,\r
+76,0,2,86,74,0,4,86,74,73,76,0,2,86,76,0,3,86,76,73,0,4,86,76,74,76,0,5,86,76,74,76,73,0,1,90,0,19,91,76,106,97,118,97,47,108,\r
+97,110,103,47,83,116,114,105,110,103,59,0,11,97,99,99,101,115,115,70,108,97,103,115,0,5,99,108,111,115,101,0,11,99,111,108,117,\r
+109,110,78,97,109,101,115,0,25,99,111,110,116,101,110,116,83,104,97,114,101,114,67,117,114,115,111,114,67,108,111,115,101,100,\r
+0,30,99,111,110,116,101,110,116,83,104,97,114,101,114,70,105,108,101,79,98,115,101,114,118,101,114,69,118,101,110,116,0,27,99,\r
+111,110,116,101,110,116,83,104,97,114,101,114,71,101,116,83,116,114,101,97,109,84,121,112,101,115,0,21,99,111,110,116,101,110,\r
+116,83,104,97,114,101,114,79,112,101,110,70,105,108,101,0,18,99,111,110,116,101,110,116,83,104,97,114,101,114,81,117,101,114,\r
+121,0,6,100,101,108,101,116,101,0,5,101,118,101,110,116,0,23,103,101,116,80,97,114,99,101,108,70,105,108,101,68,101,115,99,114,\r
+105,112,116,111,114,0,14,103,101,116,83,116,114,101,97,109,84,121,112,101,115,0,7,103,101,116,84,121,112,101,0,4,104,111,115,\r
+116,0,9,104,111,115,116,84,111,85,115,101,0,6,105,110,115,101,114,116,0,4,108,111,99,107,0,4,109,97,115,107,0,14,109,105,109,\r
+101,84,121,112,101,70,105,108,116,101,114,0,4,109,111,100,101,0,4,110,97,109,101,0,8,111,110,67,114,101,97,116,101,0,7,111,110,\r
+69,118,101,110,116,0,13,111,112,101,110,65,115,115,101,116,70,105,108,101,0,8,111,112,101,110,70,105,108,101,0,4,112,97,116,\r
+104,0,10,112,114,111,106,101,99,116,105,111,110,0,5,113,117,101,114,121,0,6,114,101,115,117,108,116,0,9,115,101,108,101,99,116,\r
+105,111,110,0,13,115,101,108,101,99,116,105,111,110,65,114,103,115,0,9,115,111,114,116,79,114,100,101,114,0,4,116,104,105,115,\r
+0,6,116,104,105,115,36,48,0,6,117,112,100,97,116,101,0,3,117,114,105,0,3,117,114,108,0,5,118,97,108,117,101,0,6,118,97,108,117,\r
+101,115,0,46,3,72,53,41,7,14,45,61,45,0,55,0,7,14,61,90,0,27,4,72,53,64,56,7,14,45,61,45,0,35,2,48,64,7,14,90,0,15,0,7,14,61,0,\r
+97,3,74,68,69,7,14,0,131,1,2,74,57,7,14,61,105,0,103,1,74,7,14,0,84,2,74,77,7,14,0,68,0,7,14,0,109,2,74,58,7,14,61,105,0,118,\r
+2,74,58,7,14,61,76,3,0,67,5,45,91,75,5,0,0,75,5,75,65,68,69,70,7,14,61,105,0,91,4,74,77,68,69,7,14,0,2,13,1,75,24,12,2,14,2,38,\r
+4,17,58,23,26,2,14,2,38,4,17,58,23,27,2,15,1,75,28,2,24,10,24,11,0,2,2,1,0,2,1,144,32,5,128,128,4,192,8,2,130,2,0,6,1,224,8,\r
+0,2,2,1,2,2,1,144,32,8,129,128,4,132,9,1,130,2,0,10,1,164,9,0,1,4,9,4,2,11,129,128,4,192,9,1,130,2,0,1,130,2,0,1,130,2,0,15,1,\r
+232,9,1,1,252,9,1,1,176,10,1,1,196,10,1,1,216,10,1,1,236,10,1,1,160,11,1,1,232,11,1,1,156,12,0,0,16,0,0,0,0,0,0,0,1,0,0,0,0,\r
+0,0,0,1,0,0,0,77,0,0,0,112,0,0,0,2,0,0,0,21,0,0,0,164,1,0,0,3,0,0,0,18,0,0,0,248,1,0,0,4,0,0,0,5,0,0,0,208,2,0,0,5,0,0,0,25,0,\r
+0,0,248,2,0,0,6,0,0,0,3,0,0,0,192,3,0,0,3,16,0,0,3,0,0,0,32,4,0,0,1,32,0,0,14,0,0,0,64,4,0,0,6,32,0,0,3,0,0,0,48,6,0,0,1,16,\r
+0,0,13,0,0,0,96,6,0,0,2,32,0,0,77,0,0,0,226,6,0,0,3,32,0,0,14,0,0,0,146,11,0,0,4,32,0,0,4,0,0,0,18,12,0,0,0,32,0,0,3,0,0,0,52,\r
+12,0,0,0,16,0,0,1,0,0,0,160,12,0,0,0,0};\r
\r
//==============================================================================\r
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \\r
\r
//==============================================================================\r
jobject openFile (const LocalRef<jobject>& contentProvider,\r
- const LocalRef<jobject>& uri, const LocalRef<jstring>& mode)\r
+ const LocalRef<jobject>& uri, const LocalRef<jstring>& mode)\r
{\r
ignoreUnused (mode);\r
\r
}\r
\r
jobject query (const LocalRef<jobject>& contentProvider, const LocalRef<jobject>& uri,\r
- const LocalRef<jobjectArray>& projection, const LocalRef<jobject>& selection,\r
- const LocalRef<jobjectArray>& selectionArgs, const LocalRef<jobject>& sortOrder)\r
+ const LocalRef<jobjectArray>& projection, const LocalRef<jobject>& selection,\r
+ const LocalRef<jobjectArray>& selectionArgs, const LocalRef<jobject>& sortOrder)\r
{\r
ignoreUnused (selection, selectionArgs, sortOrder);\r
\r
CALLBACK (contentSharerGetStreamTypes, "contentSharerGetStreamTypes", "(Landroid/net/Uri;Ljava/lang/String;)[Ljava/lang/String;") \\r
\r
\r
- DECLARE_JNI_CLASS_WITH_BYTECODE (JuceSharingContentProvider, "com/roli/juce/JuceSharingContentProvider", 16, javaJuceSharingContentProvider, sizeof(javaJuceSharingContentProvider))\r
+ DECLARE_JNI_CLASS_WITH_BYTECODE (JuceSharingContentProvider, "com/roli/juce/JuceSharingContentProvider", 16, javaJuceSharingContentProvider, sizeof (javaJuceSharingContentProvider))\r
#undef JNI_CLASS_MEMBERS\r
\r
static jobject JNICALL contentSharerQuery (JNIEnv*, jobject contentProvider, jobject uri, jobjectArray projection,\r
\r
void handleBackButtonCallback()\r
{\r
+ bool handled = false;\r
+\r
if (auto* app = JUCEApplicationBase::getInstance())\r
- app->backButtonPressed();\r
+ handled = app->backButtonPressed();\r
\r
if (Component* kiosk = Desktop::getInstance().getKioskModeComponent())\r
if (kiosk->getPeer() == this)\r
setNavBarsHidden (navBarsHidden);\r
+\r
+ if (! handled)\r
+ {\r
+ auto* env = getEnv();\r
+ LocalRef<jobject> activity (getCurrentActivity());\r
+\r
+ if (activity != nullptr)\r
+ {\r
+ jmethodID finishMethod = env->GetMethodID (AndroidActivity, "finish", "()V");\r
+\r
+ if (finishMethod != nullptr)\r
+ env->CallVoidMethod (activity.get(), finishMethod);\r
+ }\r
+ }\r
+\r
}\r
\r
void handleKeyboardHiddenCallback()\r
\r
if (scaleFactor > 0.0)\r
return scaleFactor;\r
+\r
+ return 1.0;\r
}\r
}\r
}\r
\r
Point<int> getScreenPosition (bool physical) const\r
{\r
+ auto screenBounds = (parentWindow == 0 ? bounds\r
+ : bounds.translated (parentScreenPosition.x, parentScreenPosition.y));\r
+\r
if (physical)\r
- return Desktop::getInstance().getDisplays().logicalToPhysical (bounds.getTopLeft());\r
+ return Desktop::getInstance().getDisplays().logicalToPhysical (screenBounds.getTopLeft());\r
\r
- return bounds.getTopLeft();\r
+ return screenBounds.getTopLeft();\r
}\r
\r
Rectangle<int> getBounds() const override { return bounds; }\r
friend class LinuxRepaintManager;\r
Window windowH = {}, parentWindow = {}, keyProxy = {};\r
Rectangle<int> bounds;\r
+ Point<int> parentScreenPosition;\r
Image taskbarImage;\r
bool fullScreen = false, mapped = false, focused = false;\r
Visual* visual = {};\r
\r
ScopedXLock xlock (display);\r
\r
- if (XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth) && parentWindow == 0)\r
- if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child))\r
- wx = wy = 0;\r
+ if (XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth))\r
+ {\r
+ int rootX = 0, rootY = 0;\r
+\r
+ if (! XTranslateCoordinates (display, windowH, root, 0, 0, &rootX, &rootY, &child))\r
+ rootX = rootY = 0;\r
+\r
+ if (parentWindow == 0)\r
+ {\r
+ wx = rootX;\r
+ wy = rootY;\r
+ }\r
+ else\r
+ {\r
+ parentScreenPosition = Desktop::getInstance().getDisplays().physicalToLogical (Point<int> (rootX, rootY));\r
+ }\r
+ }\r
\r
Rectangle<int> physicalBounds (wx, wy, (int) ww, (int) wh);\r
\r
g.fillAll (findColour (CodeEditorComponent::backgroundColourId));\r
\r
auto gutterSize = getGutterSize();\r
- g.reduceClipRegion (gutterSize, 0, verticalScrollBar.getX() - gutterSize, horizontalScrollBar.getY());\r
+ auto bottom = horizontalScrollBar.isVisible() ? horizontalScrollBar.getY() : getHeight();\r
+ auto right = verticalScrollBar.isVisible() ? verticalScrollBar.getX() : getWidth();\r
+\r
+ g.reduceClipRegion (gutterSize, 0, right - gutterSize, bottom);\r
\r
g.setFont (font);\r
\r
\r
ID: juce_gui_extra\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE extended GUI classes\r
description: Miscellaneous GUI classes for specialised tasks.\r
website: http://www.juce.com/juce\r
JUCE_DECLARE_SINGLETON (PushNotifications, false)\r
#endif\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Represents a notification that can be sent or received. */\r
struct Notification\r
{\r
/**@}*/\r
};\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** @name Common fields */\r
/**@{*/\r
\r
\r
/**@}*/\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** @name iOS only fields */\r
/**@{*/\r
\r
\r
/**@}*/\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** @name Android only fields */\r
/**@{*/\r
\r
};\r
\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Describes settings we want to use for current device. Note that at the\r
moment this is only used on iOS and partially on OSX.\r
\r
*/\r
void requestSettingsUsed();\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Android API level 26 or higher only: Represents notification channel through which\r
notifications will be sent. Starting from Android API level 26, you should call setupChannels()\r
at the start of your application, before posting any notifications. Then, when sending notifications,\r
*/\r
void setupChannels (const Array<ChannelGroup>& groups, const Array<Channel>& channels);\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** iOS only: sends an asynchronous request to retrieve a list of notifications that were\r
scheduled and not yet delivered.\r
\r
/** Unschedules all pending local notifications. iOS only. */\r
void removeAllPendingLocalNotifications();\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Checks whether notifications are enabled for given application.\r
On iOS and OSX this will always return true, use requestSettingsUsed() instead.\r
*/\r
/** Removes all notifications that were delivered. */\r
void removeAllDeliveredNotifications();\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Retrieves current device token. Note, it is not a good idea to cache this token\r
because it may change in the meantime. Always call this method to get the current\r
token value.\r
int timeToLive,\r
const StringPairArray& additionalData);\r
\r
- //==========================================================================\r
+ //==============================================================================\r
/** Register a listener (ideally on application startup) to receive information about\r
notifications received and any callbacks to async functions called.\r
*/\r
DECLARE_JNI_CLASS_WITH_MIN_SDK (StatusBarNotification, "android/service/notification/StatusBarNotification", 23)\r
#undef JNI_CLASS_MEMBERS\r
\r
-//==========================================================================\r
+//==============================================================================\r
#if defined(JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME)\r
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \\r
STATICMETHOD (getInstance, "getInstance", "()Lcom/google/firebase/iid/FirebaseInstanceId;") \\r
return isValidForPreApi26;\r
}\r
\r
-//==========================================================================\r
+//==============================================================================\r
struct PushNotifications::Pimpl\r
{\r
Pimpl (PushNotifications& p)\r
return true;\r
}\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void sendLocalNotification (const PushNotifications::Notification& n)\r
{\r
// All required fields have to be setup!\r
}\r
}\r
\r
- //==========================================================================\r
+ //==============================================================================\r
String getDeviceToken() const\r
{\r
#if defined(JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME)\r
#endif\r
}\r
\r
- //==========================================================================\r
+ //==============================================================================\r
void subscribeToTopic (const String& topic)\r
{\r
#if defined(JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME)\r
}\r
\r
receiver.reset (new CommandReceiver (this, inChannel));\r
+\r
+ pfds.push_back ({ threadControl[0], POLLIN, 0 });\r
+ pfds.push_back ({ receiver->getFd(), POLLIN, 0 });\r
+\r
startThread();\r
\r
xembed.reset (new XEmbedComponent (windowHandle));\r
\r
receiver->tryNextRead();\r
\r
- fd_set set;\r
- FD_ZERO (&set);\r
- FD_SET (threadControl[0], &set);\r
- FD_SET (receiver->getFd(), &set);\r
-\r
- int max_fd = jmax (threadControl[0], receiver->getFd());\r
-\r
int result = 0;\r
\r
while (result == 0 || (result < 0 && errno == EINTR))\r
- result = select (max_fd + 1, &set, nullptr, nullptr, nullptr);\r
+ result = poll (&pfds.front(), static_cast<nfds_t> (pfds.size()), 0);\r
\r
if (result < 0)\r
break;\r
int threadControl[2];\r
std::unique_ptr<XEmbedComponent> xembed;\r
WaitableEvent threadBlocker;\r
+ std::vector<pollfd> pfds;\r
};\r
\r
//==============================================================================\r
\r
ID: juce_opengl\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE OpenGL classes\r
description: Classes for rendering OpenGL in a JUCE window.\r
website: http://www.juce.com/juce\r
transform = AffineTransform::scale ((float) newArea.getWidth() / (float) localBounds.getWidth(),\r
(float) newArea.getHeight() / (float) localBounds.getHeight());\r
\r
+ nativeContext->updateWindowPosition (peer->getAreaCoveredBy (component));\r
+\r
if (canTriggerUpdate)\r
invalidateAll();\r
}\r
\r
bool initialise()\r
{\r
- return frameBuffer.initialise (context, width, height);\r
+ if (! frameBuffer.initialise (context, width, height))\r
+ return false;\r
+\r
+ frameBuffer.clear (Colours::transparentBlack);\r
+ return true;\r
}\r
\r
std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override\r
\r
ImagePixelData::Ptr clone() override\r
{\r
- Image newImage (*new OpenGLFrameBufferImage (context, width, height));\r
+ std::unique_ptr<OpenGLFrameBufferImage> im (new OpenGLFrameBufferImage (context, width, height));\r
+\r
+ if (! im->initialise())\r
+ return ImagePixelData::Ptr();\r
+\r
+ Image newImage (im.release());\r
Graphics g (newImage);\r
g.drawImageAt (Image (*this), 0, 0, false);\r
\r
if (! im->initialise())\r
return ImagePixelData::Ptr();\r
\r
- im->frameBuffer.clear (Colours::transparentBlack);\r
return *im.release();\r
}\r
\r
\r
ID: juce_osc\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE OSC classes\r
description: Open Sound Control implementation.\r
website: http://www.juce.com/juce\r
\r
ID: juce_product_unlocking\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE Online marketplace support\r
description: Classes for online product authentication\r
website: http://www.juce.com/juce\r
\r
ID: juce_video\r
vendor: juce\r
- version: 5.4.4\r
+ version: 5.4.5\r
name: JUCE video playback and capture classes\r
description: Classes for playing video and capturing camera input.\r
website: http://www.juce.com/juce\r
//==============================================================================\r
#include <juce_gui_extra/juce_gui_extra.h>\r
\r
-//=============================================================================\r
+//==============================================================================\r
/** Config: JUCE_USE_CAMERA\r
Enables camera support using the CameraDevice class (Mac, Windows, iOS, Android).\r
*/\r
#undef JUCE_USE_CAMERA\r
#endif\r
\r
-//=============================================================================\r
+//==============================================================================\r
/** Config: JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME\r
Enables synchronisation between video playback volume and OS media volume.\r
Currently supported on Android only.\r
#define JUCE_VIDEO_LOG(x) {}\r
#endif\r
\r
-//=============================================================================\r
+//==============================================================================\r
#include "playback/juce_VideoComponent.h"\r
#include "capture/juce_CameraDevice.h"\r
}\r
\r
private:\r
- //=============================================================================\r
+ //==============================================================================\r
struct StateInfo\r
{\r
int playbackStateFlag = 0, allowedActions = 0;\r
\r
namespace VideoRenderers\r
{\r
- //======================================================================\r
+ //==============================================================================\r
struct Base\r
{\r
virtual ~Base() {}\r
virtual HRESULT getVideoSize (long& videoWidth, long& videoHeight) = 0;\r
};\r
\r
- //======================================================================\r
+ //==============================================================================\r
struct VMR7 : public Base\r
{\r
VMR7() {}\r
};\r
\r
\r
- //======================================================================\r
+ //==============================================================================\r
struct EVR : public Base\r
{\r
EVR() {}\r
\r
std::unique_ptr<ComponentWatcher> componentWatcher;\r
\r
- //======================================================================\r
+ //==============================================================================\r
struct DirectShowContext : public AsyncUpdater\r
{\r
DirectShowContext (Pimpl& c) : component (c)\r
CoUninitialize();\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
void updateWindowPosition (const Rectangle<int>& newBounds)\r
{\r
nativeWindow->setWindowPosition (newBounds);\r
nativeWindow->showWindow (shouldBeVisible);\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
void repaint()\r
{\r
if (hasVideo)\r
videoRenderer->displayModeChanged();\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
void peerChanged()\r
{\r
deleteNativeWindow();\r
triggerAsyncUpdate();\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
Result loadFile (const String& fileOrURLPath)\r
{\r
jassert (state == uninitializedState);\r
}\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
void play()\r
{\r
mediaControl->Run();\r
state = pausedState;\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
Rectangle<int> getVideoSize() const noexcept\r
{\r
long width = 0, height = 0;\r
return { (int) width, (int) height };\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
double getDuration() const\r
{\r
REFTIME duration;\r
State state = uninitializedState;\r
\r
private:\r
- //======================================================================\r
+ //==============================================================================\r
enum { graphEventID = WM_APP + 0x43f0 };\r
\r
Pimpl& component;\r
\r
bool hasVideo = false, needToUpdateViewport = true, needToRecreateNativeWindow = false;\r
\r
- //======================================================================\r
+ //==============================================================================\r
bool createNativeWindow()\r
{\r
jassert (nativeWindow == nullptr);\r
return false;\r
}\r
\r
- //======================================================================\r
+ //==============================================================================\r
struct NativeWindowClass : private DeletedAtShutdown\r
{\r
bool isRegistered() const noexcept { return atom != 0; }\r
JUCE_DECLARE_NON_COPYABLE (NativeWindowClass)\r
};\r
\r
- //======================================================================\r
+ //==============================================================================\r
struct NativeWindow\r
{\r
NativeWindow (HWND parentToAddTo, void* userData)\r
\r
Result VideoComponent::load (const File& file)\r
{\r
- #if JUCE_ANDROID || JUCE_IOS\r
- ignoreUnused (file);\r
- jassertfalse;\r
- return Result::fail ("load() is not supported on this platform. Use loadAsync() instead.");\r
- #else\r
- auto r = pimpl->load (file);\r
- resized();\r
- return r;\r
- #endif\r
+ return loadInternal (file, false);\r
}\r
\r
Result VideoComponent::load (const URL& url)\r
{\r
- #if JUCE_ANDROID || JUCE_IOS\r
- // You need to use loadAsync on Android & iOS.\r
- ignoreUnused (url);\r
- jassertfalse;\r
- return Result::fail ("load() is not supported on this platform. Use loadAsync() instead.");\r
- #else\r
- auto r = pimpl->load (url);\r
- resized();\r
- return r;\r
- #endif\r
+ return loadInternal (url, false);\r
}\r
\r
void VideoComponent::loadAsync (const URL& url, std::function<void(const URL&, Result)> callback)\r
#if JUCE_ANDROID || JUCE_IOS || JUCE_MAC\r
pimpl->loadAsync (url, callback);\r
#else\r
- auto result = load (url);\r
+ auto result = loadInternal (url, true);\r
callback (url, result);\r
#endif\r
}\r
resized();\r
}\r
\r
+template<class FileOrURL>\r
+Result VideoComponent::loadInternal (const FileOrURL& fileOrUrl, bool loadAsync)\r
+{\r
+ #if JUCE_ANDROID || JUCE_IOS\r
+ ignoreUnused (fileOrUrl, loadAsync);\r
+\r
+ // You need to use loadAsync on Android & iOS.\r
+ jassertfalse;\r
+ return Result::fail ("load() is not supported on this platform. Use loadAsync() instead.");\r
+ #else\r
+ auto result = pimpl->load (fileOrUrl);\r
+\r
+ if (loadAsync)\r
+ startTimer (50);\r
+ else\r
+ resized();\r
+\r
+ return result;\r
+ #endif\r
+}\r
+\r
#endif\r
\r
} // namespace juce\r
void resized() override;\r
void timerCallback() override;\r
\r
+ template<class FileOrURL>\r
+ Result loadInternal (const FileOrURL&, bool);\r
+\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VideoComponent)\r
};\r
\r