From 6294b409f7ce7596e096a593989ff8a2c9af998f Mon Sep 17 00:00:00 2001 From: =?utf8?q?IOhannes=20m=20zm=C3=B6lnig=20=28Debian/GNU=29?= Date: Tue, 22 Oct 2019 11:44:38 +0200 Subject: [PATCH] New upstream version 5.4.5~ds0 --- .github/ISSUE_TEMPLATE.txt | 17 - .gitlab-ci.yml | 4 - BREAKING-CHANGES.txt | 52 ++ ChangeList.txt | 14 +- doxygen/process_source_files.py | 4 +- examples/DSP/OscillatorDemo.h | 6 +- .../Builds/Android/app/CMakeLists.txt | 6 +- .../Android/app/src/main/AndroidManifest.xml | 2 +- .../DemoRunner/Builds/LinuxMakefile/Makefile | 4 +- .../Builds/MacOSX/DemoRunner.entitlements | 6 + .../DemoRunner.xcodeproj/project.pbxproj | 19 +- .../DemoRunner/Builds/MacOSX/Info-App.plist | 4 +- .../VisualStudio2015/DemoRunner_App.vcxproj | 10 +- .../DemoRunner_App.vcxproj.filters | 6 + .../Builds/VisualStudio2015/resources.rc | 6 +- .../VisualStudio2017/DemoRunner_App.vcxproj | 10 +- .../DemoRunner_App.vcxproj.filters | 6 + .../Builds/VisualStudio2017/resources.rc | 6 +- .../VisualStudio2019/DemoRunner_App.vcxproj | 10 +- .../DemoRunner_App.vcxproj.filters | 6 + .../Builds/VisualStudio2019/resources.rc | 6 +- .../iOS/DemoRunner.xcodeproj/project.pbxproj | 17 +- examples/DemoRunner/Builds/iOS/Info-App.plist | 8 +- examples/DemoRunner/DemoRunner.jucer | 7 +- .../DemoRunner/JuceLibraryCode/AppConfig.h | 2 + .../DemoRunner/JuceLibraryCode/JuceHeader.h | 13 +- examples/DemoRunner/Source/Main.cpp | 2 +- .../Source/UI/DemoContentComponent.cpp | 2 +- examples/Plugins/DSPModulePluginDemo.h | 2 +- .../AudioPerformanceTest.jucer | 2 +- .../MacOSX/AudioPerformanceTest.entitlements | 6 + .../project.pbxproj | 11 + .../iOS/AudioPerformanceTest.entitlements | 6 + .../project.pbxproj | 15 +- .../JuceLibraryCode/AppConfig.h | 2 + .../JuceLibraryCode/JuceHeader.h | 9 + extras/AudioPluginHost/AudioPluginHost.jucer | 2 +- .../MacOSX/AudioPluginHost.entitlements | 6 + .../AudioPluginHost.xcodeproj/project.pbxproj | 11 + .../Builds/iOS/AudioPluginHost.entitlements | 6 + .../AudioPluginHost.xcodeproj/project.pbxproj | 15 +- .../JuceLibraryCode/AppConfig.h | 2 + .../JuceLibraryCode/JuceHeader.h | 9 + extras/AudioPluginHost/Source/HostStartup.cpp | 4 +- .../Source/Plugins/PluginGraph.cpp | 17 +- .../Source/UI/GraphEditorPanel.cpp | 2 + extras/BinaryBuilder/BinaryBuilder.jucer | 2 +- .../Builds/MacOSX/BinaryBuilder.entitlements | 6 + .../BinaryBuilder.xcodeproj/project.pbxproj | 11 + .../BinaryBuilder/JuceLibraryCode/AppConfig.h | 2 + .../JuceLibraryCode/JuceHeader.h | 9 + .../MacOSX/NetworkGraphicsDemo.entitlements | 6 + .../project.pbxproj | 11 + .../iOS/NetworkGraphicsDemo.entitlements | 6 + .../project.pbxproj | 15 +- .../JuceLibraryCode/AppConfig.h | 2 + .../JuceLibraryCode/JuceHeader.h | 9 + .../NetworkGraphicsDemo.jucer | 2 +- extras/Projucer/Builds/LinuxMakefile/Makefile | 4 +- extras/Projucer/Builds/MacOSX/Info-App.plist | 8 +- .../Builds/MacOSX/Projucer.entitlements | 6 + .../MacOSX/Projucer.xcodeproj/project.pbxproj | 19 +- .../VisualStudio2015/Projucer_App.vcxproj | 4 +- .../Builds/VisualStudio2015/resources.rc | 6 +- .../VisualStudio2017/Projucer_App.vcxproj | 4 +- .../Builds/VisualStudio2017/resources.rc | 6 +- .../VisualStudio2019/Projucer_App.vcxproj | 4 +- .../Builds/VisualStudio2019/resources.rc | 6 +- extras/Projucer/JuceLibraryCode/AppConfig.h | 2 + extras/Projucer/JuceLibraryCode/JuceHeader.h | 13 +- extras/Projucer/Projucer.jucer | 5 +- .../Windows/jucer_AboutWindowComponent.h | 6 +- .../Source/Application/jucer_Application.cpp | 8 +- .../PaintElements/jucer_PaintElementImage.cpp | 2 +- .../UI/Sidebar/jucer_ExporterTreeItems.h | 2 +- .../Project/UI/Sidebar/jucer_LiveBuildTab.h | 2 +- .../Project/UI/Sidebar/jucer_ProjectTab.h | 2 +- .../Project/UI/jucer_HeaderComponent.cpp | 22 +- .../Source/Project/UI/jucer_HeaderComponent.h | 20 +- .../UI/jucer_ModulesInformationComponent.h | 8 +- .../UI/jucer_ProjectContentComponent.cpp | 4 +- .../Projucer/Source/Project/jucer_Project.cpp | 2 +- .../ProjectSaving/jucer_ProjectExport_MSVC.h | 2 - .../ProjectSaving/jucer_ProjectExport_Xcode.h | 95 ++- .../Source/ProjectSaving/jucer_ProjectSaver.h | 13 +- .../Source/Utility/Helpers/jucer_PresetIDs.h | 2 + .../Builds/MacOSX/UnitTestRunner.entitlements | 6 + .../UnitTestRunner.xcodeproj/project.pbxproj | 11 + .../UnitTestRunner_ConsoleApp.vcxproj | 6 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 6 + .../UnitTestRunner_ConsoleApp.vcxproj | 6 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 6 + .../JuceLibraryCode/AppConfig.h | 2 + .../JuceLibraryCode/JuceHeader.h | 9 + extras/UnitTestRunner/UnitTestRunner.jucer | 2 +- extras/WindowsDLL/JuceLibraryCode/AppConfig.h | 2 + .../WindowsDLL/JuceLibraryCode/JuceHeader.h | 9 + extras/WindowsDLL/WindowsDLL.jucer | 2 +- modules/JUCE Module Format.txt | 2 +- modules/juce_analytics/juce_analytics.h | 2 +- modules/juce_audio_basics/juce_audio_basics.h | 2 +- .../utilities/juce_CatmullRomInterpolator.h | 3 + .../utilities/juce_LagrangeInterpolator.h | 3 + .../audio_io/juce_AudioDeviceManager.cpp | 15 +- .../juce_audio_devices/juce_audio_devices.cpp | 1 - .../juce_audio_devices/juce_audio_devices.h | 2 +- .../native/juce_android_Oboe.cpp | 2 +- .../native/juce_android_OpenSL.cpp | 31 +- .../native/juce_linux_Bela.cpp | 137 ++-- .../native/juce_mac_CoreMidi.cpp | 30 +- .../codecs/juce_CoreAudioFormat.cpp | 3 + .../juce_audio_formats/juce_audio_formats.h | 2 +- .../AAX/juce_AAX_Wrapper.cpp | 4 +- .../Standalone/juce_StandaloneFilterWindow.h | 13 +- .../VST/juce_VST_Wrapper.cpp | 61 +- .../VST3/juce_VST3_Wrapper.cpp | 56 +- .../juce_audio_plugin_client.h | 2 +- .../juce_AudioUnitPluginFormat.mm | 7 +- .../format_types/juce_VST3PluginFormat.cpp | 4 +- .../format_types/juce_VSTPluginFormat.cpp | 6 +- .../juce_audio_processors.h | 2 +- .../processors/juce_AudioProcessor.h | 2 +- .../processors/juce_AudioProcessorGraph.h | 5 +- .../juce_AudioProcessorParameterWithID.h | 4 +- .../juce_AudioProcessorValueTreeState.cpp | 7 +- .../juce_AudioProcessorValueTreeState.h | 12 +- .../gui/juce_AudioAppComponent.h | 2 +- modules/juce_audio_utils/juce_audio_utils.h | 2 +- ..._ios_BluetoothMidiDevicePairingDialogue.mm | 2 +- .../juce_blocks_basics/blocks/juce_Block.h | 2 +- .../blocks/juce_BlockConfigManager.h | 12 +- .../blocks/juce_TouchList.h | 2 +- .../juce_blocks_basics/juce_blocks_basics.h | 2 +- .../littlefoot/juce_LittleFootRemoteHeap.h | 117 ++-- .../protocol/juce_BlocksProtocolDefinitions.h | 15 +- .../internal/juce_BlockImplementation.cpp | 36 +- .../internal/juce_BlockSerialReader.cpp | 130 ++++ .../internal/juce_ConnectedDeviceGroup.cpp | 120 +++- .../topology/internal/juce_Detector.cpp | 40 +- .../topology/internal/juce_DetectorHolder.cpp | 17 +- .../internal/juce_MidiDeviceConnection.cpp | 2 +- .../topology/juce_PhysicalTopologySource.cpp | 21 +- .../topology/juce_PhysicalTopologySource.h | 4 +- .../topology/juce_RuleBasedTopologySource.h | 4 +- .../topology/juce_TopologySource.h | 6 +- modules/juce_box2d/juce_box2d.h | 2 +- .../juce_core/containers/juce_NamedValueSet.h | 1 - .../juce_core/containers/juce_OwnedArray.h | 24 +- modules/juce_core/files/juce_File.cpp | 22 + modules/juce_core/juce_core.cpp | 2 +- modules/juce_core/juce_core.h | 2 +- .../memory/juce_OptionalScopedPointer.h | 2 + modules/juce_core/misc/juce_WindowsRegistry.h | 2 +- .../native/juce_BasicNativeHeaders.h | 4 + .../native/juce_android_JNIHelpers.cpp | 28 +- .../native/juce_android_JNIHelpers.h | 30 +- .../juce_core/native/juce_linux_Network.cpp | 12 +- .../juce_core/native/juce_posix_NamedPipe.cpp | 11 +- .../juce_core/native/juce_posix_SharedCode.h | 29 +- .../juce_core/native/juce_win32_Registry.cpp | 22 +- modules/juce_core/network/juce_Socket.cpp | 120 ++-- modules/juce_core/network/juce_URL.cpp | 63 +- modules/juce_core/network/juce_URL.h | 13 +- .../juce_core/system/juce_CompilerSupport.h | 2 +- .../juce_core/system/juce_StandardHeader.h | 2 +- .../time/juce_PerformanceCounter.cpp | 3 +- modules/juce_cryptography/juce_cryptography.h | 2 +- .../juce_data_structures.h | 2 +- modules/juce_dsp/containers/juce_AudioBlock.h | 616 ++++++++++-------- .../containers/juce_AudioBlock_test.cpp | 342 ++++++++++ .../juce_dsp/frequency/juce_Convolution.cpp | 4 +- modules/juce_dsp/juce_dsp.cpp | 1 + modules/juce_dsp/juce_dsp.h | 2 +- modules/juce_dsp/processors/juce_Bias.h | 2 +- modules/juce_dsp/processors/juce_Gain.h | 2 +- .../juce_dsp/processors/juce_LadderFilter.h | 2 +- .../juce_dsp/processors/juce_Oversampling.cpp | 34 +- .../juce_dsp/processors/juce_Oversampling.h | 16 +- modules/juce_dsp/processors/juce_Reverb.h | 2 +- modules/juce_dsp/processors/juce_WaveShaper.h | 2 +- modules/juce_events/juce_events.h | 2 +- .../messages/juce_ApplicationBase.h | 11 +- .../messages/juce_MessageManager.cpp | 6 +- .../messages/juce_MessageManager.h | 8 +- .../juce_events/native/juce_linux_EventLoop.h | 5 +- .../native/juce_linux_Messaging.cpp | 16 +- .../contexts/juce_GraphicsContext.h | 4 +- .../fonts/juce_GlyphArrangement.h | 2 +- .../juce_graphics/fonts/juce_TextLayout.cpp | 62 -- .../geometry/juce_RectangleList.h | 2 +- modules/juce_graphics/images/juce_Image.h | 4 +- modules/juce_graphics/juce_graphics.h | 2 +- .../native/juce_mac_CoreGraphicsContext.mm | 6 +- .../juce_graphics/native/juce_mac_Fonts.mm | 2 +- modules/juce_gui_basics/juce_gui_basics.h | 2 +- modules/juce_gui_basics/layout/juce_Grid.cpp | 184 +++--- modules/juce_gui_basics/layout/juce_Grid.h | 44 +- .../juce_gui_basics/layout/juce_GridItem.cpp | 14 +- .../juce_gui_basics/layout/juce_GridItem.h | 55 +- .../juce_gui_basics/layout/juce_SidePanel.cpp | 2 +- .../juce_gui_basics/layout/juce_SidePanel.h | 8 +- .../juce_gui_basics/menus/juce_PopupMenu.cpp | 13 + .../juce_gui_basics/menus/juce_PopupMenu.h | 12 + .../native/juce_android_ContentSharer.cpp | 138 ++-- .../native/juce_android_Windowing.cpp | 19 +- .../native/juce_linux_X11_Windowing.cpp | 30 +- .../code_editor/juce_CodeEditorComponent.cpp | 5 +- modules/juce_gui_extra/juce_gui_extra.h | 2 +- .../misc/juce_PushNotifications.h | 20 +- .../native/juce_android_PushNotifications.cpp | 10 +- .../juce_linux_X11_WebBrowserComponent.cpp | 14 +- modules/juce_opengl/juce_opengl.h | 2 +- .../juce_opengl/opengl/juce_OpenGLContext.cpp | 2 + .../juce_opengl/opengl/juce_OpenGLImage.cpp | 14 +- modules/juce_osc/juce_osc.h | 2 +- .../juce_product_unlocking.h | 2 +- modules/juce_video/juce_video.h | 8 +- .../juce_video/native/juce_android_Video.h | 2 +- modules/juce_video/native/juce_win32_Video.h | 30 +- .../playback/juce_VideoComponent.cpp | 44 +- .../juce_video/playback/juce_VideoComponent.h | 3 + 221 files changed, 2714 insertions(+), 1287 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.txt delete mode 100644 .gitlab-ci.yml create mode 100644 examples/DemoRunner/Builds/MacOSX/DemoRunner.entitlements create mode 100644 extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.entitlements create mode 100644 extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.entitlements create mode 100644 extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.entitlements create mode 100644 extras/AudioPluginHost/Builds/iOS/AudioPluginHost.entitlements create mode 100644 extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.entitlements create mode 100644 extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.entitlements create mode 100644 extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.entitlements create mode 100644 extras/Projucer/Builds/MacOSX/Projucer.entitlements create mode 100644 extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.entitlements create mode 100644 modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp create mode 100644 modules/juce_dsp/containers/juce_AudioBlock_test.cpp diff --git a/.github/ISSUE_TEMPLATE.txt b/.github/ISSUE_TEMPLATE.txt deleted file mode 100644 index 2404c331..00000000 --- a/.github/ISSUE_TEMPLATE.txt +++ /dev/null @@ -1,17 +0,0 @@ -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. - diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index e91a6b17..00000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,4 +0,0 @@ -include: - - project: 'juce-repos/JUCE-utils' - file: '/CI/gitlab-ci.yml' - diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index ef40f8a0..61d162fc 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -1,6 +1,58 @@ 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 ============= diff --git a/ChangeList.txt b/ChangeList.txt index a1a755f5..bf40c1c3 100644 --- a/ChangeList.txt +++ b/ChangeList.txt @@ -3,13 +3,25 @@ This file just lists the more notable headline features. For more detailed info about minor changes and bugfixes, please see the git log! +Version 5.4.5 + - Improved message queue performance on Linux + - Added missing lifecycle callbacks on Android Q + - Refactored the AudioBlock class + - Fixed APVTS parameter update recursion + - Updated Bela code to support latest release + - Fixed issues drawing italicised text on macOS + - Fixed broken back button behaviour on Android + - Added Bluetooth permissions settings needed for iOS 13.0+ to the Projucer + - Replaced select() calls with poll() + - Various bug-fixes, improvements and documentation updates + Version 5.4.4 - Improvements to floating point number printing - Faster plug-in parameter indexing - Added support for persisting attachements to MIDI devices - Refactored Linux event loop handling - Multiple C++ modernisation improvements to the API - - Added support for macOS 10.55 and iOS 13 + - Added support for macOS 10.15 and iOS 13 - Added support for Visual Studio 2019 - Removed support for Visual Studio 2013 diff --git a/doxygen/process_source_files.py b/doxygen/process_source_files.py index 376c97db..d9862ff7 100644 --- a/doxygen/process_source_files.py +++ b/doxygen/process_source_files.py @@ -75,8 +75,10 @@ if __name__ == "__main__": "subdirectories") args = parser.parse_args() - try: + try: shutil.rmtree(args.dest_dir) + except OSError: + pass except FileNotFoundError: pass diff --git a/examples/DSP/OscillatorDemo.h b/examples/DSP/OscillatorDemo.h index 6eadf8b4..a564337e 100644 --- a/examples/DSP/OscillatorDemo.h +++ b/examples/DSP/OscillatorDemo.h @@ -73,11 +73,11 @@ struct OscillatorDemoDSP void process (const ProcessContextReplacing& context) { - tempBuffer.copy (context.getInputBlock()); - tempBuffer.multiply (static_cast (fileMix)); + tempBuffer.copyFrom (context.getInputBlock()); + tempBuffer.multiplyBy (static_cast (fileMix)); oscillators[currentOscillatorIdx].process (context); - context.getOutputBlock().multiply (static_cast (1.0 - fileMix)); + context.getOutputBlock().multiplyBy (static_cast (1.0 - fileMix)); context.getOutputBlock().add (tempBuffer); diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index caa7c4a0..a6fa1d43 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -8,7 +8,7 @@ SET(BINARY_NAME "juce_jni") 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" @@ -527,6 +527,7 @@ add_library( ${BINARY_NAME} "../../../../../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" @@ -926,6 +927,7 @@ add_library( ${BINARY_NAME} "../../../../../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" @@ -2130,6 +2132,7 @@ set_source_files_properties("../../../../../modules/juce_blocks_basics/protocol/ 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) @@ -2529,6 +2532,7 @@ set_source_files_properties("../../../../../modules/juce_data_structures/juce_da 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) diff --git a/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml b/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml index 5ea204f5..80922f54 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml +++ b/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ - diff --git a/examples/DemoRunner/Builds/LinuxMakefile/Makefile b/examples/DemoRunner/Builds/LinuxMakefile/Makefile index ae6f7824..a63eabe4 100644 --- a/examples/DemoRunner/Builds/LinuxMakefile/Makefile +++ b/examples/DemoRunner/Builds/LinuxMakefile/Makefile @@ -35,7 +35,7 @@ ifeq ($(CONFIG),Debug) 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 @@ -56,7 +56,7 @@ ifeq ($(CONFIG),Release) 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 diff --git a/examples/DemoRunner/Builds/MacOSX/DemoRunner.entitlements b/examples/DemoRunner/Builds/MacOSX/DemoRunner.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/examples/DemoRunner/Builds/MacOSX/DemoRunner.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj index df5bf5ce..0aee90e6 100644 --- a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj @@ -243,6 +243,13 @@ 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; @@ -910,6 +917,7 @@ 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; @@ -921,8 +929,8 @@ "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", @@ -955,6 +963,7 @@ 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; @@ -966,8 +975,8 @@ "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", @@ -1018,6 +1027,7 @@ 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; @@ -1064,6 +1074,7 @@ 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; diff --git a/examples/DemoRunner/Builds/MacOSX/Info-App.plist b/examples/DemoRunner/Builds/MacOSX/Info-App.plist index 3a0f5391..9aee797c 100644 --- a/examples/DemoRunner/Builds/MacOSX/Info-App.plist +++ b/examples/DemoRunner/Builds/MacOSX/Info-App.plist @@ -22,9 +22,9 @@ CFBundleSignature ???? CFBundleShortVersionString - 5.4.4 + 5.4.5 CFBundleVersion - 5.4.4 + 5.4.5 NSHumanReadableCopyright Copyright (c) 2018 - ROLI Ltd. NSHighResolutionCapable diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj index e324a45e..05447de1 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreadedDebugDLL true @@ -106,7 +106,7 @@ Full ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreaded true @@ -695,6 +695,9 @@ true + + true + true @@ -1226,6 +1229,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters index 9a2e0bc0..d669b590 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters @@ -1126,6 +1126,9 @@ JUCE Modules\juce_blocks_basics\topology\internal + + JUCE Modules\juce_blocks_basics\topology\internal + JUCE Modules\juce_blocks_basics\topology\internal @@ -1681,6 +1684,9 @@ JUCE Modules\juce_data_structures + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers diff --git a/examples/DemoRunner/Builds/VisualStudio2015/resources.rc b/examples/DemoRunner/Builds/VisualStudio2015/resources.rc index eaf88903..b9e17aa7 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/resources.rc +++ b/examples/DemoRunner/Builds/VisualStudio2015/resources.rc @@ -7,7 +7,7 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,4,0 +FILEVERSION 5,4,5,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -16,9 +16,9 @@ BEGIN VALUE "CompanyName", "ROLI Ltd.\0" VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0" VALUE "FileDescription", "DemoRunner\0" - VALUE "FileVersion", "5.4.4\0" + VALUE "FileVersion", "5.4.5\0" VALUE "ProductName", "DemoRunner\0" - VALUE "ProductVersion", "5.4.4\0" + VALUE "ProductVersion", "5.4.5\0" END END diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj index 040005b8..cd93c15b 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreadedDebugDLL true @@ -106,7 +106,7 @@ Full ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreaded true @@ -695,6 +695,9 @@ true + + true + true @@ -1226,6 +1229,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters index 2ffed545..1c01ce48 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters @@ -1126,6 +1126,9 @@ JUCE Modules\juce_blocks_basics\topology\internal + + JUCE Modules\juce_blocks_basics\topology\internal + JUCE Modules\juce_blocks_basics\topology\internal @@ -1681,6 +1684,9 @@ JUCE Modules\juce_data_structures + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers diff --git a/examples/DemoRunner/Builds/VisualStudio2017/resources.rc b/examples/DemoRunner/Builds/VisualStudio2017/resources.rc index eaf88903..b9e17aa7 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/resources.rc +++ b/examples/DemoRunner/Builds/VisualStudio2017/resources.rc @@ -7,7 +7,7 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,4,0 +FILEVERSION 5,4,5,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -16,9 +16,9 @@ BEGIN VALUE "CompanyName", "ROLI Ltd.\0" VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0" VALUE "FileDescription", "DemoRunner\0" - VALUE "FileVersion", "5.4.4\0" + VALUE "FileVersion", "5.4.5\0" VALUE "ProductName", "DemoRunner\0" - VALUE "ProductVersion", "5.4.4\0" + VALUE "ProductVersion", "5.4.5\0" END END diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index abf67e40..8ce8e592 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreadedDebugDLL true @@ -106,7 +106,7 @@ Full ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreaded true @@ -695,6 +695,9 @@ true + + true + true @@ -1226,6 +1229,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 2bcd6278..71680ce4 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -1126,6 +1126,9 @@ JUCE Modules\juce_blocks_basics\topology\internal + + JUCE Modules\juce_blocks_basics\topology\internal + JUCE Modules\juce_blocks_basics\topology\internal @@ -1681,6 +1684,9 @@ JUCE Modules\juce_data_structures + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers diff --git a/examples/DemoRunner/Builds/VisualStudio2019/resources.rc b/examples/DemoRunner/Builds/VisualStudio2019/resources.rc index eaf88903..b9e17aa7 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/resources.rc +++ b/examples/DemoRunner/Builds/VisualStudio2019/resources.rc @@ -7,7 +7,7 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,4,0 +FILEVERSION 5,4,5,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -16,9 +16,9 @@ BEGIN VALUE "CompanyName", "ROLI Ltd.\0" VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0" VALUE "FileDescription", "DemoRunner\0" - VALUE "FileVersion", "5.4.4\0" + VALUE "FileVersion", "5.4.5\0" VALUE "ProductName", "DemoRunner\0" - VALUE "ProductVersion", "5.4.4\0" + VALUE "ProductVersion", "5.4.5\0" END END diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj index 0f01890c..5751f074 100644 --- a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj @@ -889,7 +889,6 @@ 91A9A0FE9DF4F4E10009EEC7 = { isa = PBXGroup; children = ( - 0CCFDC1D1C7B8A12BF4822F1, 9683F931FA1B8B85FA8C4BD8, 5A0B2CEF393A25C6D4B1B76C, 61F3057D838D7DABB0FA3D34, @@ -903,8 +902,8 @@ 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; @@ -920,8 +919,8 @@ "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", @@ -950,8 +949,8 @@ 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; @@ -967,8 +966,8 @@ "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", @@ -999,7 +998,7 @@ 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; @@ -1049,7 +1048,7 @@ 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; diff --git a/examples/DemoRunner/Builds/iOS/Info-App.plist b/examples/DemoRunner/Builds/iOS/Info-App.plist index 483c3852..39de13f0 100644 --- a/examples/DemoRunner/Builds/iOS/Info-App.plist +++ b/examples/DemoRunner/Builds/iOS/Info-App.plist @@ -7,6 +7,10 @@ This app requires audio input. If you do not have an audio interface connected it will use the built-in microphone. NSCameraUsageDescription This app requires access to the camera to function correctly. + NSBluetoothAlwaysUsageDescription + This app requires access to Bluetooth to function correctly. + NSBluetoothPeripheralUsageDescription + This app requires access to Bluetooth to function correctly. LSRequiresIPhoneOS UIViewControllerBasedStatusBarAppearance @@ -26,9 +30,9 @@ CFBundleSignature ???? CFBundleShortVersionString - 5.4.4 + 5.4.5 CFBundleVersion - 5.4.4 + 5.4.5 NSHumanReadableCopyright Copyright (c) 2018 - ROLI Ltd. NSHighResolutionCapable diff --git a/examples/DemoRunner/DemoRunner.jucer b/examples/DemoRunner/DemoRunner.jucer index f661d0ed..4a28f30c 100644 --- a/examples/DemoRunner/DemoRunner.jucer +++ b/examples/DemoRunner/DemoRunner.jucer @@ -1,7 +1,7 @@ - @@ -121,7 +121,8 @@ + customXcodeResourceFolders="../Assets" smallIcon="YyqWd2" bigIcon="YyqWd2" + iosBluetoothPermissionNeeded="1"> diff --git a/examples/DemoRunner/JuceLibraryCode/AppConfig.h b/examples/DemoRunner/JuceLibraryCode/AppConfig.h index 7c6bfaa7..fd7cbb98 100644 --- a/examples/DemoRunner/JuceLibraryCode/AppConfig.h +++ b/examples/DemoRunner/JuceLibraryCode/AppConfig.h @@ -47,6 +47,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_analytics 1 #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 diff --git a/examples/DemoRunner/JuceLibraryCode/JuceHeader.h b/examples/DemoRunner/JuceLibraryCode/JuceHeader.h index 06f7f814..c1d016dd 100644 --- a/examples/DemoRunner/JuceLibraryCode/JuceHeader.h +++ b/examples/DemoRunner/JuceLibraryCode/JuceHeader.h @@ -36,6 +36,15 @@ #include +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. @@ -47,7 +56,7 @@ namespace ProjectInfo { const char* const projectName = "DemoRunner"; const char* const companyName = "ROLI Ltd."; - const char* const versionString = "5.4.4"; - const int versionNumber = 0x50404; + const char* const versionString = "5.4.5"; + const int versionNumber = 0x50405; } #endif diff --git a/examples/DemoRunner/Source/Main.cpp b/examples/DemoRunner/Source/Main.cpp index 3f58c792..edbd8f8e 100644 --- a/examples/DemoRunner/Source/Main.cpp +++ b/examples/DemoRunner/Source/Main.cpp @@ -108,7 +108,7 @@ public: mainWindow.reset (new MainAppWindow (getApplicationName())); } - void backButtonPressed() override { mainWindow->getMainComponent().getSidePanel().showOrHide (false); } + bool backButtonPressed() override { mainWindow->getMainComponent().getSidePanel().showOrHide (false); return true; } void shutdown() override { mainWindow = nullptr; } //============================================================================== diff --git a/examples/DemoRunner/Source/UI/DemoContentComponent.cpp b/examples/DemoRunner/Source/UI/DemoContentComponent.cpp index 19e61be7..1c6d9a35 100644 --- a/examples/DemoRunner/Source/UI/DemoContentComponent.cpp +++ b/examples/DemoRunner/Source/UI/DemoContentComponent.cpp @@ -156,7 +156,7 @@ void DemoContentComponent::setDemo (const String& category, int selectedDemoInde bool DemoContentComponent::isShowingHomeScreen() const noexcept { - return isComponentIntroDemo (demoContent->getComponent()); + return isComponentIntroDemo (demoContent->getComponent()) && getCurrentTabIndex() == 0; } void DemoContentComponent::showHomeScreen() diff --git a/examples/Plugins/DSPModulePluginDemo.h b/examples/Plugins/DSPModulePluginDemo.h index a814a91a..43d4f2ef 100644 --- a/examples/Plugins/DSPModulePluginDemo.h +++ b/examples/Plugins/DSPModulePluginDemo.h @@ -196,7 +196,7 @@ public: process (dsp::ProcessContextReplacing (firstChan)); for (size_t chan = 1; chan < block.getNumChannels(); ++chan) - block.getSingleChannelBlock (chan).copy (firstChan); + block.getSingleChannelBlock (chan).copyFrom (firstChan); } } diff --git a/extras/AudioPerformanceTest/AudioPerformanceTest.jucer b/extras/AudioPerformanceTest/AudioPerformanceTest.jucer index 895863e8..f030db71 100644 --- a/extras/AudioPerformanceTest/AudioPerformanceTest.jucer +++ b/extras/AudioPerformanceTest/AudioPerformanceTest.jucer @@ -1,7 +1,7 @@ diff --git a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.entitlements b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj index 282962a3..0772d9b1 100644 --- a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj +++ b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj @@ -336,6 +336,13 @@ 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; @@ -494,6 +501,7 @@ 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; @@ -536,6 +544,7 @@ 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; @@ -596,6 +605,7 @@ 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; @@ -642,6 +652,7 @@ 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; diff --git a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.entitlements b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj index 81affeea..979f3567 100644 --- a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj +++ b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj @@ -355,6 +355,13 @@ 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; @@ -527,8 +534,8 @@ 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; @@ -570,8 +577,8 @@ 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; @@ -615,7 +622,7 @@ 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; @@ -665,7 +672,7 @@ 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; diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h b/extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h index 954761b2..9032f6ee 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h +++ b/extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h @@ -47,6 +47,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 #define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h b/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h index 82feea7c..1368bac8 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h +++ b/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h @@ -27,6 +27,15 @@ #include +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. diff --git a/extras/AudioPluginHost/AudioPluginHost.jucer b/extras/AudioPluginHost/AudioPluginHost.jucer index 5aff91d4..8ace7ccf 100644 --- a/extras/AudioPluginHost/AudioPluginHost.jucer +++ b/extras/AudioPluginHost/AudioPluginHost.jucer @@ -2,7 +2,7 @@ + + + + + diff --git a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj index c99c747c..8ba981fe 100644 --- a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj @@ -585,6 +585,13 @@ 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; @@ -770,6 +777,7 @@ 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; @@ -814,6 +822,7 @@ 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; @@ -876,6 +885,7 @@ 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; @@ -922,6 +932,7 @@ 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; diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.entitlements b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj index b7546839..56ef09ea 100644 --- a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj @@ -582,6 +582,13 @@ 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; @@ -779,8 +786,8 @@ 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; @@ -824,8 +831,8 @@ 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; @@ -871,7 +878,7 @@ 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; @@ -921,7 +928,7 @@ 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; diff --git a/extras/AudioPluginHost/JuceLibraryCode/AppConfig.h b/extras/AudioPluginHost/JuceLibraryCode/AppConfig.h index f2c41a73..0a43cec5 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/AppConfig.h +++ b/extras/AudioPluginHost/JuceLibraryCode/AppConfig.h @@ -49,6 +49,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 #define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 diff --git a/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h b/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h index 01d36b3b..5b63c7a0 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h +++ b/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h @@ -31,6 +31,15 @@ #include "BinaryData.h" +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. diff --git a/extras/AudioPluginHost/Source/HostStartup.cpp b/extras/AudioPluginHost/Source/HostStartup.cpp index 49d8e52e..e45009ac 100644 --- a/extras/AudioPluginHost/Source/HostStartup.cpp +++ b/extras/AudioPluginHost/Source/HostStartup.cpp @@ -126,10 +126,12 @@ public: JUCEApplicationBase::quit(); } - void backButtonPressed() override + bool backButtonPressed() override { if (mainWindow->graphHolder != nullptr) mainWindow->graphHolder->hideLastSidePanel(); + + return true; } const String getApplicationName() override { return "Juce Plug-In Host"; } diff --git a/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp b/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp index 0eeb43cd..082911e5 100644 --- a/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp +++ b/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp @@ -325,9 +325,13 @@ static XmlElement* createNodeXml (AudioProcessorGraph::Node* const node) noexcep if (auto* plugin = dynamic_cast (node->getProcessor())) { auto e = new XmlElement ("FILTER"); - e->setAttribute ("uid", (int) node->nodeID.uid); - e->setAttribute ("x", node->properties ["x"].toString()); - e->setAttribute ("y", node->properties ["y"].toString()); + + e->setAttribute ("uid", (int) node->nodeID.uid); + e->setAttribute ("x", node->properties ["x"].toString()); + e->setAttribute ("y", node->properties ["y"].toString()); + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + e->setAttribute ("DPIAware", node->properties["DPIAware"].toString()); + #endif for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i) { @@ -401,8 +405,11 @@ void PluginGraph::createNodeFromXml (const XmlElement& xml) node->getProcessor()->setStateInformation (m.getData(), (int) m.getSize()); } - node->properties.set ("x", xml.getDoubleAttribute ("x")); - node->properties.set ("y", xml.getDoubleAttribute ("y")); + node->properties.set ("x", xml.getDoubleAttribute ("x")); + node->properties.set ("y", xml.getDoubleAttribute ("y")); + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + node->properties.set ("DPIAware", xml.getDoubleAttribute ("DPIAware")); + #endif for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i) { diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp index bea2b67b..a74497f6 100644 --- a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp +++ b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp @@ -442,12 +442,14 @@ struct GraphEditorPanel::PluginComponent : public Component, case 10: showWindow (PluginWindow::Type::normal); break; case 11: showWindow (PluginWindow::Type::programs); break; case 12: showWindow (PluginWindow::Type::generic) ; break; + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE case 13: { if (auto* node = graph.graph.getNodeForId (pluginID)) node->properties.set ("DPIAware", ! node->properties ["DPIAware"]); break; } + #endif case 14: showWindow (PluginWindow::Type::debug); break; case 20: showWindow (PluginWindow::Type::audioIO); break; case 21: testStateSaveLoad(); break; diff --git a/extras/BinaryBuilder/BinaryBuilder.jucer b/extras/BinaryBuilder/BinaryBuilder.jucer index 5efa1e04..8c13340b 100644 --- a/extras/BinaryBuilder/BinaryBuilder.jucer +++ b/extras/BinaryBuilder/BinaryBuilder.jucer @@ -1,7 +1,7 @@ diff --git a/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.entitlements b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj index a6b08ca8..479760bf 100644 --- a/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj +++ b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj @@ -36,6 +36,13 @@ 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; @@ -170,6 +177,7 @@ 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; @@ -210,6 +218,7 @@ 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; @@ -268,6 +277,7 @@ 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; @@ -314,6 +324,7 @@ 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; diff --git a/extras/BinaryBuilder/JuceLibraryCode/AppConfig.h b/extras/BinaryBuilder/JuceLibraryCode/AppConfig.h index 16358316..ee326c03 100644 --- a/extras/BinaryBuilder/JuceLibraryCode/AppConfig.h +++ b/extras/BinaryBuilder/JuceLibraryCode/AppConfig.h @@ -47,6 +47,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_core 1 diff --git a/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h b/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h index ce4d6d90..990925e6 100644 --- a/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h +++ b/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h @@ -17,6 +17,15 @@ #include +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. diff --git a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.entitlements b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj index bf306b31..8d4427ba 100644 --- a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj +++ b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj @@ -171,6 +171,13 @@ 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; @@ -630,6 +637,7 @@ 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; @@ -672,6 +680,7 @@ 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; @@ -732,6 +741,7 @@ 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; @@ -778,6 +788,7 @@ 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; diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.entitlements b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj index e1c662c3..00987e47 100644 --- a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj +++ b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj @@ -190,6 +190,13 @@ 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; @@ -663,8 +670,8 @@ 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; @@ -706,8 +713,8 @@ 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; @@ -751,7 +758,7 @@ 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; @@ -801,7 +808,7 @@ 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; diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h b/extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h index 22f64728..f0cdeab2 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h @@ -47,6 +47,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 #define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h b/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h index b72437d2..e7443e58 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h @@ -31,6 +31,15 @@ #include "BinaryData.h" +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. diff --git a/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer b/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer index f8843645..79a87de7 100644 --- a/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer +++ b/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer @@ -1,7 +1,7 @@ diff --git a/extras/Projucer/Builds/LinuxMakefile/Makefile b/extras/Projucer/Builds/LinuxMakefile/Makefile index ccf330cb..25b49046 100644 --- a/extras/Projucer/Builds/LinuxMakefile/Makefile +++ b/extras/Projucer/Builds/LinuxMakefile/Makefile @@ -35,7 +35,7 @@ ifeq ($(CONFIG),Debug) 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 @@ -56,7 +56,7 @@ ifeq ($(CONFIG),Release) 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 diff --git a/extras/Projucer/Builds/MacOSX/Info-App.plist b/extras/Projucer/Builds/MacOSX/Info-App.plist index 00eb365f..c2214834 100644 --- a/extras/Projucer/Builds/MacOSX/Info-App.plist +++ b/extras/Projucer/Builds/MacOSX/Info-App.plist @@ -18,6 +18,10 @@ + NSMicrophoneUsageDescription + This app requires audio input. If you do not have an audio interface connected it will use the built-in microphone. + NSCameraUsageDescription + This app requires access to the camera to function correctly. CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile @@ -33,9 +37,9 @@ CFBundleSignature ???? CFBundleShortVersionString - 5.4.4 + 5.4.5 CFBundleVersion - 5.4.4 + 5.4.5 NSHumanReadableCopyright ROLI Ltd. NSHighResolutionCapable diff --git a/extras/Projucer/Builds/MacOSX/Projucer.entitlements b/extras/Projucer/Builds/MacOSX/Projucer.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/Projucer/Builds/MacOSX/Projucer.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj index e5af3062..6db9d905 100644 --- a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj +++ b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj @@ -1973,6 +1973,13 @@ 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; @@ -3198,6 +3205,7 @@ 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; @@ -3207,8 +3215,8 @@ "_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", @@ -3241,6 +3249,7 @@ 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; @@ -3250,8 +3259,8 @@ "_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", @@ -3301,6 +3310,7 @@ 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; @@ -3347,6 +3357,7 @@ 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; diff --git a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj index 6405421d..a025ed09 100644 --- a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreadedDebugDLL true @@ -106,7 +106,7 @@ Full ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreaded true diff --git a/extras/Projucer/Builds/VisualStudio2015/resources.rc b/extras/Projucer/Builds/VisualStudio2015/resources.rc index 6ac9b991..c4143235 100644 --- a/extras/Projucer/Builds/VisualStudio2015/resources.rc +++ b/extras/Projucer/Builds/VisualStudio2015/resources.rc @@ -7,7 +7,7 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,4,0 +FILEVERSION 5,4,5,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -16,9 +16,9 @@ BEGIN VALUE "CompanyName", "ROLI Ltd.\0" VALUE "LegalCopyright", "ROLI Ltd.\0" VALUE "FileDescription", "Projucer\0" - VALUE "FileVersion", "5.4.4\0" + VALUE "FileVersion", "5.4.5\0" VALUE "ProductName", "Projucer\0" - VALUE "ProductVersion", "5.4.4\0" + VALUE "ProductVersion", "5.4.5\0" END END diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj index 3e780f2f..7c8751a7 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreadedDebug true @@ -106,7 +106,7 @@ Full ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreaded true diff --git a/extras/Projucer/Builds/VisualStudio2017/resources.rc b/extras/Projucer/Builds/VisualStudio2017/resources.rc index 6ac9b991..c4143235 100644 --- a/extras/Projucer/Builds/VisualStudio2017/resources.rc +++ b/extras/Projucer/Builds/VisualStudio2017/resources.rc @@ -7,7 +7,7 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,4,0 +FILEVERSION 5,4,5,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -16,9 +16,9 @@ BEGIN VALUE "CompanyName", "ROLI Ltd.\0" VALUE "LegalCopyright", "ROLI Ltd.\0" VALUE "FileDescription", "Projucer\0" - VALUE "FileVersion", "5.4.4\0" + VALUE "FileVersion", "5.4.5\0" VALUE "ProductName", "Projucer\0" - VALUE "ProductVersion", "5.4.4\0" + VALUE "ProductVersion", "5.4.5\0" END END diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj index d13b3cde..0a28052e 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreadedDebug true @@ -106,7 +106,7 @@ Full ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _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) + _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) MultiThreaded true diff --git a/extras/Projucer/Builds/VisualStudio2019/resources.rc b/extras/Projucer/Builds/VisualStudio2019/resources.rc index 6ac9b991..c4143235 100644 --- a/extras/Projucer/Builds/VisualStudio2019/resources.rc +++ b/extras/Projucer/Builds/VisualStudio2019/resources.rc @@ -7,7 +7,7 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,4,0 +FILEVERSION 5,4,5,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -16,9 +16,9 @@ BEGIN VALUE "CompanyName", "ROLI Ltd.\0" VALUE "LegalCopyright", "ROLI Ltd.\0" VALUE "FileDescription", "Projucer\0" - VALUE "FileVersion", "5.4.4\0" + VALUE "FileVersion", "5.4.5\0" VALUE "ProductName", "Projucer\0" - VALUE "ProductVersion", "5.4.4\0" + VALUE "ProductVersion", "5.4.5\0" END END diff --git a/extras/Projucer/JuceLibraryCode/AppConfig.h b/extras/Projucer/JuceLibraryCode/AppConfig.h index 3620ea15..dffd5af7 100644 --- a/extras/Projucer/JuceLibraryCode/AppConfig.h +++ b/extras/Projucer/JuceLibraryCode/AppConfig.h @@ -66,6 +66,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_analytics 1 #define JUCE_MODULE_AVAILABLE_juce_core 1 diff --git a/extras/Projucer/JuceLibraryCode/JuceHeader.h b/extras/Projucer/JuceLibraryCode/JuceHeader.h index f3f49db0..765b4265 100644 --- a/extras/Projucer/JuceLibraryCode/JuceHeader.h +++ b/extras/Projucer/JuceLibraryCode/JuceHeader.h @@ -25,6 +25,15 @@ #include "BinaryData.h" +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. @@ -36,7 +45,7 @@ namespace ProjectInfo { const char* const projectName = "Projucer"; const char* const companyName = "ROLI Ltd."; - const char* const versionString = "5.4.4"; - const int versionNumber = 0x50404; + const char* const versionString = "5.4.5"; + const int versionNumber = 0x50405; } #endif diff --git a/extras/Projucer/Projucer.jucer b/extras/Projucer/Projucer.jucer index 4f6b4077..6f4f7080 100644 --- a/extras/Projucer/Projucer.jucer +++ b/extras/Projucer/Projucer.jucer @@ -1,14 +1,15 @@ + extraFrameworks="AudioUnit; Accelerate; AVFoundation; CoreAudio; CoreAudioKit; CoreMIDI; DiscRecording; QuartzCore; AudioToolbox; OpenGL; QTKit; QuickTime" + microphonePermissionNeeded="1" cameraPermissionNeeded="1"> diff --git a/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h index aa33c486..cdaae6cd 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h @@ -81,19 +81,19 @@ public: auto leftSlice = bounds.removeFromLeft (150); auto centreSlice = bounds; - //====================================================================== + //============================================================================== rightSlice.removeFromRight (20); auto iconSlice = rightSlice.removeFromRight (100); huckleberryLogoBounds = iconSlice.removeFromBottom (100).toFloat(); - //====================================================================== + //============================================================================== juceLogoBounds = leftSlice.removeFromTop (150).toFloat(); juceLogoBounds.setWidth (juceLogoBounds.getWidth() + 100); juceLogoBounds.setHeight (juceLogoBounds.getHeight() + 100); copyrightLabel.setBounds (leftSlice.removeFromBottom (20)); - //====================================================================== + //============================================================================== auto titleHeight = 40; centreSlice.removeFromTop ((centreSlice.getHeight() / 2) - (titleHeight / 2)); diff --git a/extras/Projucer/Source/Application/jucer_Application.cpp b/extras/Projucer/Source/Application/jucer_Application.cpp index 67f20243..b1f8aef0 100644 --- a/extras/Projucer/Source/Application/jucer_Application.cpp +++ b/extras/Projucer/Source/Application/jucer_Application.cpp @@ -510,7 +510,7 @@ void ProjucerApplication::createColourSchemeItems (PopupMenu& menu) menu.addSubMenu ("Colour Scheme", colourSchemeMenu); - //========================================================================== + //============================================================================== PopupMenu editorColourSchemeMenu; auto& appearanceSettings = getAppSettings().appearance; @@ -625,7 +625,7 @@ void ProjucerApplication::createExamplesPopupMenu (PopupMenu& menu) noexcept } } -//========================================================================== +//============================================================================== static File getJUCEExamplesDirectoryPathFromGlobal() { auto globalPath = File::createFileWithoutCheckingPath (getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString() @@ -722,7 +722,7 @@ void ProjucerApplication::findAndLaunchExample (int selectedIndex) Analytics::getInstance()->logEvent ("Example Opened", data, ProjucerAnalyticsEvent::exampleEvent); } -//========================================================================== +//============================================================================== static String getPlatformSpecificFileExtension() { #if JUCE_MAC @@ -940,7 +940,7 @@ void ProjucerApplication::launchDemoRunner() } } -//========================================================================== +//============================================================================== void ProjucerApplication::handleMainMenuCommand (int menuItemID) { if (menuItemID >= recentProjectsBaseID && menuItemID < (recentProjectsBaseID + 100)) diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp index 0fa9313f..5b6a4a4f 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp @@ -147,7 +147,7 @@ void PaintElementImage::fillInGeneratedCode (GeneratedCode& code, String& paintM r << " jassert (" << imageVariable << " != 0);\n" << " if (" << imageVariable << " != 0)\n" - << " " << imageVariable << "->drawWithin (g, Rectangle (x, y, width, height),\n" + << " " << imageVariable << "->drawWithin (g, Rectangle (x, y, width, height).toFloat(),\n" << " " << String::repeatedString (" ", imageVariable.length() + 18) << (mode == stretched ? "RectanglePlacement::stretchToFit" : (mode == proportionalReducingOnly ? "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize" diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h index 33a4a326..4cc84f02 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h @@ -368,7 +368,7 @@ private: Project& project; ValueTree exportersTree; - //========================================================================== + //============================================================================== void valueTreeChildAdded (ValueTree& parentTree, ValueTree&) override { refreshIfNeeded (parentTree); } void valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int) override { refreshIfNeeded (parentTree); } void valueTreeChildOrderChanged (ValueTree& parentTree, int, int) override { refreshIfNeeded (parentTree); } diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h index 11b215e7..096c53f6 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h @@ -172,7 +172,7 @@ private: Rectangle textBounds; - //========================================================================== + //============================================================================== String getErrorMessage() { showDownloadButton = false; diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h index bcd061f9..dbeb8a1b 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h @@ -27,7 +27,7 @@ #pragma once -//========================================================================== +//============================================================================== struct ProjectSettingsComponent : public Component, private ChangeListener { diff --git a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp index 53b8a620..193fe17d 100644 --- a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp +++ b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp @@ -35,7 +35,7 @@ #include "../../LiveBuildEngine/jucer_DiagnosticMessage.h" #include "../../LiveBuildEngine/jucer_CompileEngineClient.h" -//====================================================================== +//============================================================================== HeaderComponent::HeaderComponent() { addAndMakeVisible (configLabel); @@ -66,13 +66,13 @@ HeaderComponent::~HeaderComponent() } } -//====================================================================== +//============================================================================== void HeaderComponent::resized() { auto bounds = getLocalBounds(); configLabel.setFont ({ bounds.getHeight() / 3.0f }); - //====================================================================== + //============================================================================== { auto headerBounds = bounds.removeFromLeft (tabsWidth); @@ -87,7 +87,7 @@ void HeaderComponent::resized() projectNameLabel.setBounds (headerBounds); } - //====================================================================== + //============================================================================== auto exporterWidth = jmin (400, bounds.getWidth() / 2); Rectangle exporterBounds (0, 0, exporterWidth, bounds.getHeight()); @@ -114,7 +114,7 @@ void HeaderComponent::paint (Graphics& g) runAppButton->getWidth(), runAppButton->getHeight()); } -//====================================================================== +//============================================================================== void HeaderComponent::setCurrentProject (Project* p) noexcept { project = p; @@ -148,7 +148,7 @@ void HeaderComponent::setCurrentProject (Project* p) noexcept } } -//====================================================================== +//============================================================================== void HeaderComponent::updateExporters() noexcept { auto selectedName = getSelectedExporterName(); @@ -203,7 +203,7 @@ bool HeaderComponent::canCurrentExporterLaunchProject() const noexcept return false; } -//====================================================================== +//============================================================================== int HeaderComponent::getUserButtonWidth() const noexcept { return userSettingsButton->getWidth(); @@ -215,7 +215,7 @@ void HeaderComponent::sidebarTabsWidthChanged (int newWidth) noexcept resized(); } -//====================================================================== +//============================================================================== void HeaderComponent::showUserSettings() noexcept { #if JUCER_ENABLE_GPL_MODE @@ -233,7 +233,7 @@ void HeaderComponent::showUserSettings() noexcept userSettingsWindow = &CallOutBox::launchAsynchronously (content, userSettingsButton->getScreenBounds(), nullptr); } -//========================================================================== +//============================================================================== void HeaderComponent::lookAndFeelChanged() { if (userSettingsWindow != nullptr) @@ -261,7 +261,7 @@ void HeaderComponent::timerCallback() repaint(); } -//====================================================================== +//============================================================================== static void sendProjectButtonAnalyticsEvent (StringRef label) { StringPairArray data; @@ -351,7 +351,7 @@ void HeaderComponent::updateUserAvatar() noexcept } } -//====================================================================== +//============================================================================== void HeaderComponent::buildPing() { if (! isTimerRunning()) diff --git a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h index 540b3840..0ebac873 100644 --- a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h +++ b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h @@ -43,33 +43,33 @@ public: HeaderComponent(); ~HeaderComponent() override; - //========================================================================== + //============================================================================== void resized() override; void paint (Graphics&) override; - //========================================================================== + //============================================================================== void setCurrentProject (Project*) noexcept; - //========================================================================== + //============================================================================== void updateExporters() noexcept; String getSelectedExporterName() const noexcept; bool canCurrentExporterLaunchProject() const noexcept; - //========================================================================== + //============================================================================== int getUserButtonWidth() const noexcept; void sidebarTabsWidthChanged (int newWidth) noexcept; - //========================================================================== + //============================================================================== void showUserSettings() noexcept; private: - //========================================================================== + //============================================================================== void lookAndFeelChanged() override; void changeListenerCallback (ChangeBroadcaster* source) override; void valueChanged (Value&) override; void timerCallback() override; - //========================================================================== + //============================================================================== void valueTreeChildAdded (ValueTree& parentTree, ValueTree&) override { updateIfNeeded (parentTree); } void valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int) override { updateIfNeeded (parentTree); } void valueTreeChildOrderChanged (ValueTree& parentTree, int, int) override { updateIfNeeded (parentTree); } @@ -80,19 +80,19 @@ private: updateExporters(); } - //========================================================================== + //============================================================================== void initialiseButtons() noexcept; void updateName() noexcept; void updateExporterButton() noexcept; void updateUserAvatar() noexcept; - //========================================================================== + //============================================================================== void buildPing(); void buildFinished (bool); void setRunAppButtonState (bool); - //========================================================================== + //============================================================================== int tabsWidth = 200; bool isBuilding = false; diff --git a/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h b/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h index 81a4c68f..0b2ef9f6 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h +++ b/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h @@ -122,24 +122,24 @@ public: bounds.removeFromLeft (5); g.setColour (rowIsSelected ? findColour (defaultHighlightedTextColourId) : findColour (widgetTextColourId)); - //====================================================================== + //============================================================================== auto moduleID = project.getEnabledModules().getModuleID (rowNumber); g.drawFittedText (moduleID, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (0) * width)), Justification::centredLeft, 1); - //====================================================================== + //============================================================================== auto version = project.getEnabledModules().getModuleInfo (moduleID).getVersion(); if (version.isEmpty()) version = "?"; g.drawFittedText (version, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (1) * width)), Justification::centredLeft, 1); - //====================================================================== + //============================================================================== auto copyLocally = project.getEnabledModules().shouldCopyModuleFilesLocally (moduleID).getValue() ? "Yes" : "No"; g.drawFittedText (copyLocally, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (2) * width)), Justification::centredLeft, 1); - //====================================================================== + //============================================================================== String pathText; if (project.getEnabledModules().shouldUseGlobalPath (moduleID)) diff --git a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp index 52d52045..8e3a367c 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp +++ b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp @@ -255,7 +255,7 @@ void ProjectContentComponent::rebuildProjectTabs() addAndMakeVisible (sidebarTabs); createProjectTabs(); - //====================================================================== + //============================================================================== auto& settings = project->getStoredProperties(); auto lastTreeWidth = settings.getValue ("projectPanelWidth").getIntValue(); @@ -271,7 +271,7 @@ void ProjectContentComponent::rebuildProjectTabs() projectTab->setPanelHeightProportion (i, settings.getValue ("projectTabPanelHeight" + String (i), "1") .getFloatValue()); - //====================================================================== + //============================================================================== resizerBar.reset (new ResizableEdgeComponent (&sidebarTabs, &sidebarSizeConstrainer, ResizableEdgeComponent::rightEdge)); addAndMakeVisible (resizerBar.get()); diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index d6519f3a..45f5b351 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -1036,7 +1036,7 @@ void Project::createPropertyEditors (PropertyListBuilder& props) "Include BinaryData.h in the JuceHeader.h file"); props.add (new TextPropertyComponent (binaryDataNamespaceValue, "BinaryData Namespace", 256, false), - "The namespace containing the binary assests."); + "The namespace containing the binary assets."); props.add (new ChoicePropertyComponent (cppStandardValue, "C++ Language Standard", { "C++11", "C++14", "C++17", "Use Latest" }, diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index e7617adb..f47c1331 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h @@ -570,8 +570,6 @@ public: if (cppStandard == "11") // VS doesn't support the C++11 flag so we have to bump it to C++14 cppStandard = "14"; - else if (cppStandard == "17") // nor does it support the C++17 flag, so we'll just use latest for now until it's added - cppStandard = "latest"; cl->createNewChildElement ("LanguageStandard")->addTextElement ("stdcpp" + cppStandard); } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index 0a2e995d..1764dcaa 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -104,6 +104,9 @@ public: cameraPermissionNeededValue (settings, Ids::cameraPermissionNeeded, getUndoManager()), cameraPermissionTextValue (settings, Ids::cameraPermissionText, getUndoManager(), "This app requires access to the camera to function correctly."), + iosBluetoothPermissionNeededValue (settings, Ids::iosBluetoothPermissionNeeded, getUndoManager()), + iosBluetoothPermissionTextValue (settings, Ids::iosBluetoothPermissionText, getUndoManager(), + "This app requires access to Bluetooth to function correctly."), uiFileSharingEnabledValue (settings, Ids::UIFileSharingEnabled, getUndoManager()), uiSupportsDocumentBrowserValue (settings, Ids::UISupportsDocumentBrowser, getUndoManager()), uiStatusBarHiddenValue (settings, Ids::UIStatusBarHidden, getUndoManager()), @@ -173,6 +176,9 @@ public: bool isCameraPermissionEnabled() const { return cameraPermissionNeededValue.get(); } String getCameraPermissionTextString() const { return cameraPermissionTextValue.get(); } + bool isBluetoothPermissionEnabled() const { return iosBluetoothPermissionNeededValue.get(); } + String getBluetoothPermissionTextString() const { return iosBluetoothPermissionTextValue.get(); } + bool isInAppPurchasesEnabled() const { return iosInAppPurchasesValue.get(); } bool isBackgroundAudioEnabled() const { return iosBackgroundAudioValue.get(); } bool isBackgroundBleEnabled() const { return iosBackgroundBleValue.get(); } @@ -187,7 +193,7 @@ public: bool shouldKeepCustomXcodeSchemes() const { return keepCustomXcodeSchemesValue.get(); } - String getIosDevelopmentTeamIDString() const { return iosDevelopmentTeamIDValue.get(); } + String getDevelopmentTeamIDString() const { return iosDevelopmentTeamIDValue.get(); } String getAppGroupIdString() const { return iosAppGroupsIDValue.get(); } String getDefaultLaunchStoryboardName() const { jassert (iOS); return "LaunchScreen"; } @@ -398,6 +404,17 @@ public: "Camera Access Text", 1024, false), "A short description of why your app requires camera access."); + if (iOS) + { + props.add (new ChoicePropertyComponent (iosBluetoothPermissionNeededValue, "Bluetooth Access"), + "Enable this to allow your app to use Bluetooth on iOS 13.0 and above. " + "The user of your app will be prompted to grant Bluetooth access permissions."); + + props.add (new TextPropertyComponentWithEnablement (iosBluetoothPermissionTextValue, iosBluetoothPermissionNeededValue, + "Bluetooth Access Text", 1024, false), + "A short description of why your app requires Bluetooth access."); + } + props.add (new ChoicePropertyComponent (iosInAppPurchasesValue, "In-App Purchases Capability"), "Enable this to grant your app the capability for in-app purchases. " "This option requires that you specify a valid Development Team ID."); @@ -468,7 +485,7 @@ public: "This is useful if you want to use different bundle identifiers for Mac and iOS exporters in the same project."); props.add (new TextPropertyComponent (iosDevelopmentTeamIDValue, "Development Team ID", 10, false), - "The Development Team ID to be used for setting up code-signing your iOS app. This is a ten-character " + "The Development Team ID to be used for setting up code-signing your app. This is a ten-character " "string (for example, \"S7B6T5XJ2Q\") that describes the distribution certificate Apple issued to you. " "You can find this string in the OS X app Keychain Access under \"Certificates\"."); @@ -610,7 +627,7 @@ protected: osxArchitecture (config, Ids::osxArchitecture, getUndoManager(), osxArch_Default), customXcodeFlags (config, Ids::customXcodeFlags, getUndoManager()), plistPreprocessorDefinitions (config, Ids::plistPreprocessorDefinitions, getUndoManager()), - codeSignIdentity (config, Ids::codeSigningIdentity, getUndoManager(), iOS ? "iPhone Developer" : "Mac Developer"), + codeSignIdentity (config, Ids::codeSigningIdentity, getUndoManager()), fastMathEnabled (config, Ids::fastMath, getUndoManager()), stripLocalSymbolsEnabled (config, Ids::stripLocalSymbols, getUndoManager()), pluginBinaryCopyStepEnabled (config, Ids::enablePluginBinaryCopyStep, getUndoManager(), true), @@ -627,7 +644,7 @@ protected: optimisationLevelValue.setDefault (isDebug() ? gccO0 : gccO3); } - //========================================================================== + //============================================================================== void createConfigProperties (PropertyListBuilder& props) override { addXcodePluginInstallPathProperties (props); @@ -684,7 +701,7 @@ protected: return "${CURRENT_ARCH}"; } - //========================================================================== + //============================================================================== String getOSXArchitectureString() const { return osxArchitecture.get(); } String getPListPreprocessorDefinitionsString() const { return plistPreprocessorDefinitions.get(); } @@ -698,7 +715,6 @@ protected: String getOSXDeploymentTargetString() const { return osxDeploymentTarget.get(); } String getCodeSignIdentityString() const { return codeSignIdentity.get(); } - bool isUsingDefaultCodeSignIdentity() const { return codeSignIdentity.isUsingDefault(); } String getiOSDeploymentTargetString() const { return iosDeploymentTarget.get(); } @@ -711,7 +727,7 @@ protected: String getUnityPluginBinaryLocationString() const { return unityPluginBinaryLocation.get(); } private: - //========================================================================== + //============================================================================== bool iOS; ValueWithDefault osxSDKVersion, osxDeploymentTarget, iosDeploymentTarget, osxArchitecture, @@ -720,7 +736,7 @@ protected: vstBinaryLocation, vst3BinaryLocation, auBinaryLocation, rtasBinaryLocation, aaxBinaryLocation, unityPluginBinaryLocation; - //========================================================================== + //============================================================================== void addXcodePluginInstallPathProperties (PropertyListBuilder& props) { auto isBuildingAnyPlugins = (project.shouldBuildVST() || project.shouldBuildVST3() || project.shouldBuildAU() @@ -1070,7 +1086,7 @@ public: { auto attributes = getID() + " = { "; - auto developmentTeamID = owner.getIosDevelopmentTeamIDString(); + auto developmentTeamID = owner.getDevelopmentTeamIDString(); if (developmentTeamID.isNotEmpty()) { @@ -1308,7 +1324,9 @@ public: if (owner.iOS) { s.set ("ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon"); - s.set ("ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME", "LaunchImage"); + + if (! owner.shouldAddStoryboardToProject()) + s.set ("ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME", "LaunchImage"); } else { @@ -1323,15 +1341,15 @@ public: s.set ("GCC_VERSION", gccVersion); s.set ("CLANG_LINK_OBJC_RUNTIME", "NO"); - if (isUsingCodeSigning (config)) - { - s.set (owner.iOS ? "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"" : "CODE_SIGN_IDENTITY", - config.getCodeSignIdentityString().quoted()); + auto codeSigningIdentity = owner.getCodeSigningIdentity (config); + s.set (owner.iOS ? "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"" : "CODE_SIGN_IDENTITY", + codeSigningIdentity.quoted()); + + if (codeSigningIdentity.isNotEmpty()) s.set ("PROVISIONING_PROFILE_SPECIFIER", "\"\""); - } - if (owner.getIosDevelopmentTeamIDString().isNotEmpty()) - s.set ("DEVELOPMENT_TEAM", owner.getIosDevelopmentTeamIDString()); + if (owner.getDevelopmentTeamIDString().isNotEmpty()) + s.set ("DEVELOPMENT_TEAM", owner.getDevelopmentTeamIDString()); if (shouldAddEntitlements()) s.set ("CODE_SIGN_ENTITLEMENTS", owner.getEntitlementsFileName().quoted()); @@ -1480,7 +1498,6 @@ public: } } - flags.add (owner.replacePreprocessorTokens (config, owner.getExtraLinkerFlagsString())); flags.add (owner.getExternalLibraryFlags (config)); auto libs = owner.xcodeLibs; @@ -1490,6 +1507,7 @@ public: flags.add (getLinkerFlagForLib (l)); } + flags.add (owner.replacePreprocessorTokens (config, owner.getExtraLinkerFlagsString())); flags = getCleanedStringArray (flags); } @@ -1517,6 +1535,12 @@ public: if (owner.iOS) { + if (owner.isBluetoothPermissionEnabled()) + { + addPlistDictionaryKey (dict, "NSBluetoothAlwaysUsageDescription", owner.getBluetoothPermissionTextString()); + addPlistDictionaryKey (dict, "NSBluetoothPeripheralUsageDescription", owner.getBluetoothPermissionTextString()); // needed for pre iOS 13.0 + } + addPlistDictionaryKeyBool (dict, "LSRequiresIPhoneOS", true); if (type != AudioUnitv3PlugIn) @@ -1919,12 +1943,6 @@ public: return {}; } - bool isUsingCodeSigning (const XcodeBuildConfiguration& config) const - { - return (! config.isUsingDefaultCodeSignIdentity()) - || owner.getIosDevelopmentTeamIDString().isNotEmpty(); - } - //============================================================================== const XcodeProjectExporter& owner; @@ -1958,7 +1976,7 @@ private: iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue, appSandboxValue, appSandboxOptionsValue, hardenedRuntimeValue, hardenedRuntimeOptionsValue, - microphonePermissionNeededValue, microphonePermissionsTextValue, cameraPermissionNeededValue, cameraPermissionTextValue, + microphonePermissionNeededValue, microphonePermissionsTextValue, cameraPermissionNeededValue, cameraPermissionTextValue, iosBluetoothPermissionNeededValue, iosBluetoothPermissionTextValue, uiFileSharingEnabledValue, uiSupportsDocumentBrowserValue, uiStatusBarHiddenValue, documentExtensionsValue, iosInAppPurchasesValue, iosBackgroundAudioValue, iosBackgroundBleValue, iosPushNotificationsValue, iosAppGroupsValue, iCloudPermissionsValue, iosDevelopmentTeamIDValue, iosAppGroupsIDValue, keepCustomXcodeSchemesValue, useHeaderMapValue, customLaunchStoryboardValue, @@ -2115,10 +2133,7 @@ private: void addFilesAndGroupsToProject (StringArray& topLevelGroupIDs) const { - auto entitlements = getEntitlements(); - - if (entitlements.size() > 0) - topLevelGroupIDs.add (addEntitlementsFile (entitlements)); + addEntitlementsFile(); for (auto& group : getAllGroups()) { @@ -2526,6 +2541,16 @@ private: return sanitisePath (searchPath); } + String getCodeSigningIdentity (const XcodeBuildConfiguration& config) const + { + auto identity = config.getCodeSignIdentityString(); + + if (identity.isEmpty() && getDevelopmentTeamIDString().isNotEmpty()) + return iOS ? "iPhone Developer" : "Mac Developer"; + + return identity; + } + StringPairArray getProjectSettings (const XcodeBuildConfiguration& config) const { StringPairArray s; @@ -2583,18 +2608,15 @@ private: s.set ("ONLY_ACTIVE_ARCH", "YES"); } + s.set (iOS ? "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"" : "CODE_SIGN_IDENTITY", + getCodeSigningIdentity (config).quoted()); + if (iOS) { - s.set ("\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"", config.getCodeSignIdentityString().quoted()); s.set ("SDKROOT", "iphoneos"); s.set ("TARGETED_DEVICE_FAMILY", getDeviceFamilyString().quoted()); s.set ("IPHONEOS_DEPLOYMENT_TARGET", config.getiOSDeploymentTargetString()); } - else - { - if (! config.isUsingDefaultCodeSignIdentity() || getIosDevelopmentTeamIDString().isNotEmpty()) - s.set ("CODE_SIGN_IDENTITY", config.getCodeSignIdentityString().quoted()); - } s.set ("ZERO_LINK", "NO"); @@ -3128,7 +3150,7 @@ private: return entitlements; } - String addEntitlementsFile (StringPairArray entitlements) const + String addEntitlementsFile() const { String content = "\n" @@ -3136,6 +3158,7 @@ private: "\n" "\n"; + auto entitlements = getEntitlements(); auto keys = entitlements.getAllKeys(); for (auto& key : keys) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h index b21a1aff..c2711ecc 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h @@ -458,7 +458,9 @@ private: << newLine << "// END SECTION A" << newLine << newLine - << "#define JUCE_USE_DARK_SPLASH_SCREEN " << (project.getSplashScreenColourString() == "Dark" ? "1" : "0") << newLine; + << "#define JUCE_USE_DARK_SPLASH_SCREEN " << (project.getSplashScreenColourString() == "Dark" ? "1" : "0") << newLine + << newLine + << "#define JUCE_PROJUCER_VERSION 0x" << String::toHexString (ProjectInfo::versionNumber) << newLine; out << newLine << "//==============================================================================" << newLine; @@ -556,6 +558,15 @@ private: out << CodeHelpers::createIncludeStatement (project.getBinaryDataHeaderFile(), appConfigFile) << newLine; out << newLine + << "#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION" << newLine + << " /** If you've hit this error then the version of the Projucer that was used to generate this project is" << newLine + << " older than the version of the JUCE modules being included. To fix this error, re-save your project" << newLine + << " using the latest version of the Projucer or, if you aren't using the Projucer to manage your project," << newLine + << " remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file." << newLine + << " */" << newLine + << " #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 + << "#endif" << newLine + << newLine << "#if ! DONT_SET_USING_JUCE_NAMESPACE" << newLine << " // If your code uses a lot of JUCE classes, then this will obviously save you" << newLine << " // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE." << newLine diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h index 1b6ad202..5a3ef9cb 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h @@ -252,6 +252,8 @@ namespace Ids DECLARE_ID (iCloudPermissions); DECLARE_ID (iosDevelopmentTeamID); DECLARE_ID (iosAppGroupsId); + DECLARE_ID (iosBluetoothPermissionNeeded); + DECLARE_ID (iosBluetoothPermissionText); DECLARE_ID (duplicateAppExResourcesFolder); DECLARE_ID (buildToolsVersion); DECLARE_ID (gradleVersion); diff --git a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.entitlements b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.entitlements new file mode 100644 index 00000000..6631ffa6 --- /dev/null +++ b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.entitlements @@ -0,0 +1,6 @@ + + + + + + diff --git a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj index 9ecf9cae..02ced2bb 100644 --- a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj +++ b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj @@ -398,6 +398,13 @@ 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; @@ -686,6 +693,7 @@ 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; @@ -728,6 +736,7 @@ 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; @@ -788,6 +797,7 @@ 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; @@ -834,6 +844,7 @@ 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; diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj index 6dafd30d..b6d6721d 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj @@ -692,6 +692,9 @@ true + + true + true @@ -1082,6 +1085,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters index 8a3ee6ec..40c5b96d 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1075,6 +1075,9 @@ JUCE Modules\juce_blocks_basics\topology\internal + + JUCE Modules\juce_blocks_basics\topology\internal + JUCE Modules\juce_blocks_basics\topology\internal @@ -1489,6 +1492,9 @@ JUCE Modules\juce_data_structures + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 9b33ada2..8fda3982 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -692,6 +692,9 @@ true + + true + true @@ -1082,6 +1085,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index 7b2bfeee..473a89cd 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1075,6 +1075,9 @@ JUCE Modules\juce_blocks_basics\topology\internal + + JUCE Modules\juce_blocks_basics\topology\internal + JUCE Modules\juce_blocks_basics\topology\internal @@ -1489,6 +1492,9 @@ JUCE Modules\juce_data_structures + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers diff --git a/extras/UnitTestRunner/JuceLibraryCode/AppConfig.h b/extras/UnitTestRunner/JuceLibraryCode/AppConfig.h index 2257f535..e270488f 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/AppConfig.h +++ b/extras/UnitTestRunner/JuceLibraryCode/AppConfig.h @@ -47,6 +47,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_analytics 1 #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 diff --git a/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h b/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h index b4cfd548..1b016eba 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h +++ b/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h @@ -35,6 +35,15 @@ #include +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. diff --git a/extras/UnitTestRunner/UnitTestRunner.jucer b/extras/UnitTestRunner/UnitTestRunner.jucer index a57260a9..6cbcabaa 100644 --- a/extras/UnitTestRunner/UnitTestRunner.jucer +++ b/extras/UnitTestRunner/UnitTestRunner.jucer @@ -1,7 +1,7 @@ diff --git a/extras/WindowsDLL/JuceLibraryCode/AppConfig.h b/extras/WindowsDLL/JuceLibraryCode/AppConfig.h index ab226083..146de870 100644 --- a/extras/WindowsDLL/JuceLibraryCode/AppConfig.h +++ b/extras/WindowsDLL/JuceLibraryCode/AppConfig.h @@ -47,6 +47,8 @@ #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#define JUCE_PROJUCER_VERSION 0x50405 + //============================================================================== #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 #define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 diff --git a/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h b/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h index c7101cce..91fef65b 100644 --- a/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h +++ b/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h @@ -30,6 +30,15 @@ #include +#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION + /** If you've hit this error then the version of the Projucer that was used to generate this project is + older than the version of the JUCE modules being included. To fix this error, re-save your project + using the latest version of the Projucer or, if you aren't using the Projucer to manage your project, + remove the JUCE_PROJUCER_VERSION define from the AppConfig.h file. + */ + #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." +#endif + #if ! DONT_SET_USING_JUCE_NAMESPACE // If your code uses a lot of JUCE classes, then this will obviously save you // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. diff --git a/extras/WindowsDLL/WindowsDLL.jucer b/extras/WindowsDLL/WindowsDLL.jucer index 34f601e7..d713ca99 100644 --- a/extras/WindowsDLL/WindowsDLL.jucer +++ b/extras/WindowsDLL/WindowsDLL.jucer @@ -1,7 +1,7 @@ diff --git a/modules/JUCE Module Format.txt b/modules/JUCE Module Format.txt index 571f7b03..ebe41e9f 100644 --- a/modules/JUCE Module Format.txt +++ b/modules/JUCE Module Format.txt @@ -108,7 +108,7 @@ OS X: "i386", for example). Visual Studio: - VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio + libs/VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio release, arch is the target architecture in Visual Studio ("x64" or "Win32", for example), and {runtime} is the type of the run-time library indicated by the corresponding compiler flag ("MD", "MDd", "MT", "MTd"). diff --git a/modules/juce_analytics/juce_analytics.h b/modules/juce_analytics/juce_analytics.h index f119738f..0bf9255e 100644 --- a/modules/juce_analytics/juce_analytics.h +++ b/modules/juce_analytics/juce_analytics.h @@ -35,7 +35,7 @@ ID: juce_analytics vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE analytics classes description: Classes to collect analytics and send to destinations website: http://www.juce.com/juce diff --git a/modules/juce_audio_basics/juce_audio_basics.h b/modules/juce_audio_basics/juce_audio_basics.h index 617c7ced..83a10831 100644 --- a/modules/juce_audio_basics/juce_audio_basics.h +++ b/modules/juce_audio_basics/juce_audio_basics.h @@ -31,7 +31,7 @@ ID: juce_audio_basics vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE audio and MIDI data classes description: Classes for audio buffer manipulation, midi message handling, synthesis, etc. website: http://www.juce.com/juce diff --git a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h b/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h index ab3ca754..2d89a34e 100644 --- a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h +++ b/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h @@ -42,6 +42,9 @@ public: CatmullRomInterpolator() noexcept; ~CatmullRomInterpolator() noexcept; + CatmullRomInterpolator (CatmullRomInterpolator&&) noexcept = default; + CatmullRomInterpolator& operator= (CatmullRomInterpolator&&) noexcept = default; + /** Resets the state of the interpolator. Call this when there's a break in the continuity of the input data stream. */ diff --git a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h index 6914e465..25598e75 100644 --- a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h +++ b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h @@ -42,6 +42,9 @@ public: LagrangeInterpolator() noexcept; ~LagrangeInterpolator() noexcept; + LagrangeInterpolator (LagrangeInterpolator&&) noexcept = default; + LagrangeInterpolator& operator= (LagrangeInterpolator&&) noexcept = default; + /** Resets the state of the interpolator. Call this when there's a break in the continuity of the input data stream. */ diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp index 7dbe0101..a26a3bf4 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp @@ -1098,12 +1098,19 @@ bool AudioDeviceManager::isMidiInputEnabled (const String& name) const void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd) { - for (auto& device : MidiInput::getAvailableDevices()) + if (name.isEmpty()) { - if (device.name == name) + addMidiInputDeviceCallback ({}, callbackToAdd); + } + else + { + for (auto& device : MidiInput::getAvailableDevices()) { - addMidiInputDeviceCallback (device.identifier, callbackToAdd); - return; + if (device.name == name) + { + addMidiInputDeviceCallback (device.identifier, callbackToAdd); + return; + } } } } diff --git a/modules/juce_audio_devices/juce_audio_devices.cpp b/modules/juce_audio_devices/juce_audio_devices.cpp index d6e1e990..a7f816e9 100644 --- a/modules/juce_audio_devices/juce_audio_devices.cpp +++ b/modules/juce_audio_devices/juce_audio_devices.cpp @@ -149,7 +149,6 @@ installed, or you've not got your paths set up correctly to find its header files. */ - #include #include #include #endif diff --git a/modules/juce_audio_devices/juce_audio_devices.h b/modules/juce_audio_devices/juce_audio_devices.h index 8b476b90..20a2c5f6 100644 --- a/modules/juce_audio_devices/juce_audio_devices.h +++ b/modules/juce_audio_devices/juce_audio_devices.h @@ -31,7 +31,7 @@ ID: juce_audio_devices vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE audio and MIDI I/O device classes description: Classes to play and record from audio and MIDI I/O devices website: http://www.juce.com/juce diff --git a/modules/juce_audio_devices/native/juce_android_Oboe.cpp b/modules/juce_audio_devices/native/juce_android_Oboe.cpp index 3fbf5fe7..4d202507 100644 --- a/modules/juce_audio_devices/native/juce_android_Oboe.cpp +++ b/modules/juce_audio_devices/native/juce_android_Oboe.cpp @@ -1434,7 +1434,7 @@ public: } private: - //============================================================================= + //============================================================================== void* (*threadEntryProc) (void*) = nullptr; void* threadUserPtr = nullptr; diff --git a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp index 3f0229f8..7e67c1d0 100644 --- a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp +++ b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp @@ -315,6 +315,12 @@ struct OpenSLEngineHolder SlRef engine; }; +OpenSLEngineHolder& getEngineHolder() +{ + static OpenSLEngineHolder holder; + return holder; +} + //============================================================================== class SLRealtimeThread; @@ -458,11 +464,11 @@ public: SLObjectItf obj = nullptr; - SharedResourcePointer holder; + auto& holder = getEngineHolder(); - if (auto e = *holder->engine) + if (auto e = *holder.engine) { - auto status = e->CreateAudioPlayer (holder->engine, &obj, &source, &sink, 2, + auto status = e->CreateAudioPlayer (holder.engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired); if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize(obj, 0) != SL_RESULT_SUCCESS) @@ -503,11 +509,11 @@ public: SLObjectItf obj = nullptr; - SharedResourcePointer holder; + auto& holder = getEngineHolder(); - if (auto e = *holder->engine) + if (auto e = *holder.engine) { - auto status = e->CreateAudioRecorder (holder->engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired); + auto status = e->CreateAudioRecorder (holder.engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired); if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) { @@ -556,9 +562,10 @@ public: if (outputChannels > 0) { - SharedResourcePointer holder; + auto& holder = getEngineHolder(); SLObjectItf obj = nullptr; - auto err = (*holder->engine)->CreateOutputMix (holder->engine, &obj, 0, nullptr, nullptr); + + auto err = (*holder.engine)->CreateOutputMix (holder.engine, &obj, 0, nullptr, nullptr); if (err != SL_RESULT_SUCCESS || obj == nullptr || *obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) @@ -814,7 +821,7 @@ public: outputLatency = (int) ((longestLatency * outputLatency) / totalLatency) & ~15; // You can only create this class if you are sure that your hardware supports OpenSL - jassert (engineHolder->slLibrary.getNativeHandle() != nullptr); + jassert (getEngineHolder().slLibrary.getNativeHandle() != nullptr); } ~OpenSLAudioIODevice() override @@ -1032,8 +1039,6 @@ private: friend class SLRealtimeThread; //============================================================================== - SharedResourcePointer engineHolder; - int actualBufferSize = 0, sampleRate = 0, audioBuffersToEnqueue = 0; int inputLatency, outputLatency; bool deviceOpen = false, audioProcessingEnabled = true; @@ -1346,13 +1351,13 @@ public: } private: - //============================================================================= + //============================================================================== static void staticFinished (SLAndroidSimpleBufferQueueItf, void* context) { static_cast (context)->finished(); } - //============================================================================= + //============================================================================== DynamicLibrary slLibrary { "libOpenSLES.so" }; SlRef engine; diff --git a/modules/juce_audio_devices/native/juce_linux_Bela.cpp b/modules/juce_audio_devices/native/juce_linux_Bela.cpp index 363e3c57..b13eceb5 100755 --- a/modules/juce_audio_devices/native/juce_linux_Bela.cpp +++ b/modules/juce_audio_devices/native/juce_linux_Bela.cpp @@ -56,7 +56,7 @@ public: void poll() { - int receivedBytes = 0; + size_t receivedBytes = 0; for (;;) { @@ -70,7 +70,7 @@ public: if (receivedBytes == buffer.size()) { - pushMidiData (receivedBytes); + pushMidiData (static_cast (receivedBytes)); receivedBytes = 0; } } @@ -89,6 +89,11 @@ public: return devices; } + void pushMidiMessage (juce::MidiMessage& message) + { + concatenator.pushMidiData (message.getRawData(), message.getRawDataSize(), Time::getMillisecondCounter() * 0.001, midiInput, *midiCallback); + } + private: void pushMidiData (int length) { @@ -144,7 +149,7 @@ private: auto subCount = snd_rawmidi_info_get_subdevices_count (info); - for (int sub = 0; sub < subCount; ++sub) + for (size_t sub = 0; sub < subCount; ++sub) { snd_rawmidi_info_set_subdevice (info, sub); @@ -161,8 +166,8 @@ private: snd_ctl_close (ctl); } - String midiPort; MidiInput* const midiInput; + String midiPort; MidiInputCallback* const midiCallback; Midi midi; @@ -190,8 +195,26 @@ public: } //============================================================================== - StringArray getOutputChannelNames() override { return { "Out #1", "Out #2" }; } - StringArray getInputChannelNames() override { return { "In #1", "In #2" }; } + StringArray getOutputChannelNames() override + { + StringArray result; + + for (int i = 1; i <= actualNumberOfOutputs; i++) + result.add ("Out #" + std::to_string (i)); + + return result; + } + + StringArray getInputChannelNames() override + { + StringArray result; + + for (int i = 1; i <= actualNumberOfInputs; i++) + result.add ("In #" + std::to_string (i)); + + return result; + } + Array getAvailableSampleRates() override { return { 44100.0 }; } Array getAvailableBufferSizes() override { /* TODO: */ return { getDefaultBufferSize() }; } int getDefaultBufferSize() override { return defaultSettings.periodSize; } @@ -213,15 +236,27 @@ public: auto numIns = getNumContiguousSetBits (inputChannels); auto numOuts = getNumContiguousSetBits (outputChannels); - settings.useAnalog = 0; - settings.useDigital = 0; - settings.numAudioInChannels = numIns; - settings.numAudioOutChannels = numOuts; + // Input and Output channels are numbered as follows + // + // 0 .. 1 - audio + // 2 .. 9 - analog + + if (numIns > 2 || numOuts > 2) + { + settings.useAnalog = true; + settings.numAnalogInChannels = std::max (numIns - 2, 8); + settings.numAnalogOutChannels = std::max (numOuts - 2, 8); + settings.uniformSampleRate = true; + } + + settings.numAudioInChannels = std::max (numIns, 2); + settings.numAudioOutChannels = std::max (numOuts, 2); + settings.detectUnderruns = 1; settings.setup = setupCallback; settings.render = renderCallback; settings.cleanup = cleanupCallback; - settings.interleave = 1; + settings.interleave = 0; if (bufferSizeSamples > 0) settings.periodSize = bufferSizeSamples; @@ -240,10 +275,7 @@ public: actualNumberOfInputs = jmin (numIns, actualNumberOfInputs); actualNumberOfOutputs = jmin (numOuts, actualNumberOfOutputs); - audioInBuffer.setSize (actualNumberOfInputs, actualBufferSize); channelInBuffer.calloc (actualNumberOfInputs); - - audioOutBuffer.setSize (actualNumberOfOutputs, actualBufferSize); channelOutBuffer.calloc (actualNumberOfOutputs); return {}; @@ -265,10 +297,7 @@ public: actualNumberOfInputs = 0; actualNumberOfOutputs = 0; - audioInBuffer.setSize (0, 0); channelInBuffer.free(); - - audioOutBuffer.setSize (0, 0); channelOutBuffer.free(); } } @@ -298,9 +327,6 @@ public: } else { - audioInBuffer.clear(); - audioOutBuffer.clear(); - callback = newCallback; isRunning = (Bela_startAudio() == 0); @@ -342,7 +368,7 @@ public: //============================================================================== int getCurrentBufferSizeSamples() override { return actualBufferSize; } double getCurrentSampleRate() override { return 44100.0; } - int getCurrentBitDepth() override { return 24; } + int getCurrentBitDepth() override { return 16; } BigInteger getActiveOutputChannels() const override { BigInteger b; b.setRange (0, actualNumberOfOutputs, true); return b; } BigInteger getActiveInputChannels() const override { BigInteger b; b.setRange (0, actualNumberOfInputs, true); return b; } int getOutputLatencyInSamples() override { /* TODO */ return 0; } @@ -353,12 +379,13 @@ public: static const char* const belaTypeName; private: + //============================================================================== bool setup (BelaContext& context) { actualBufferSize = context.audioFrames; - actualNumberOfInputs = context.audioInChannels; - actualNumberOfOutputs = context.audioOutChannels; + actualNumberOfInputs = context.audioInChannels + context.analogInChannels; + actualNumberOfOutputs = context.audioOutChannels + context.analogOutChannels; isBelaOpen = true; firstCallback = true; @@ -384,59 +411,29 @@ private: if (callback != nullptr) { jassert (context.audioFrames <= actualBufferSize); - auto numSamples = jmin (context.audioFrames, actualBufferSize); - auto interleaved = ((context.flags & BELA_FLAG_INTERLEAVED) != 0); - auto numIns = jmin (actualNumberOfInputs, (int) context.audioInChannels); - auto numOuts = jmin (actualNumberOfOutputs, (int) context.audioOutChannels); - - int ch; - - if (interleaved && context.audioInChannels > 1) - { - for (ch = 0; ch < numIns; ++ch) - { - using DstSampleType = AudioData::Pointer; - using SrcSampleType = AudioData::Pointer; + jassert ((context.flags & BELA_FLAG_INTERLEAVED) == 0); - channelInBuffer[ch] = audioInBuffer.getWritePointer (ch); - DstSampleType dstData (audioInBuffer.getWritePointer (ch)); - SrcSampleType srcData (context.audioIn + ch, context.audioInChannels); - dstData.convertSamples (srcData, numSamples); - } - } - else + // Setup channelInBuffers + for (int ch = 0; ch < actualNumberOfInputs; ++ch) { - for (ch = 0; ch < numIns; ++ch) - channelInBuffer[ch] = context.audioIn + (ch * numSamples); + if (ch < analogChannelStart) + channelInBuffer[ch] = &context.audioIn[ch * context.audioFrames]; + else + channelInBuffer[ch] = &context.analogIn[(ch - analogChannelStart) * context.analogFrames]; } - for (; ch < actualNumberOfInputs; ++ch) + // Setup channelOutBuffers + for (int ch = 0; ch < actualNumberOfOutputs; ++ch) { - channelInBuffer[ch] = audioInBuffer.getWritePointer(ch); - zeromem (audioInBuffer.getWritePointer (ch), sizeof (float) * numSamples); + if (ch < analogChannelStart) + channelOutBuffer[ch] = &context.audioOut[ch * context.audioFrames]; + else + channelOutBuffer[ch] = &context.analogOut[(ch - analogChannelStart) * context.audioFrames]; } - for (int i = 0; i < actualNumberOfOutputs; ++i) - channelOutBuffer[i] = ((interleaved && context.audioOutChannels > 1) || i >= context.audioOutChannels ? audioOutBuffer.getWritePointer (i) - : context.audioOut + (i * numSamples)); - callback->audioDeviceIOCallback (channelInBuffer.getData(), actualNumberOfInputs, channelOutBuffer.getData(), actualNumberOfOutputs, - numSamples); - - if (interleaved && context.audioOutChannels > 1) - { - for (int i = 0; i < numOuts; ++i) - { - using DstSampleType = AudioData::Pointer; - using SrcSampleType = AudioData::Pointer; - - SrcSampleType srcData (channelOutBuffer[i]); - DstSampleType dstData (context.audioOut + i, context.audioOutChannels); - - dstData.convertSamples (srcData, numSamples); - } - } + context.audioFrames); } } @@ -448,6 +445,7 @@ private: callback->audioDeviceStopped(); } + const int analogChannelStart = 2; //============================================================================== uint64_t expectedElapsedAudioSamples = 0; @@ -490,10 +488,11 @@ private: uint32_t actualBufferSize = 0; int actualNumberOfInputs = 0, actualNumberOfOutputs = 0; - AudioBuffer audioInBuffer, audioOutBuffer; HeapBlock channelInBuffer; HeapBlock channelOutBuffer; + bool includeAnalogSupport; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODevice) }; @@ -504,7 +503,6 @@ struct BelaAudioIODeviceType : public AudioIODeviceType { BelaAudioIODeviceType() : AudioIODeviceType ("Bela") {} - // TODO: support analog outputs StringArray getDeviceNames (bool) const override { return StringArray (BelaAudioIODevice::belaTypeName); } void scanForDevices() override {} int getDefaultDeviceIndex (bool) const override { return 0; } @@ -513,6 +511,7 @@ struct BelaAudioIODeviceType : public AudioIODeviceType AudioIODevice* createDevice (const String& outputName, const String& inputName) override { + // TODO: switching whether to support analog/digital with possible multiple Bela device types? if (outputName == BelaAudioIODevice::belaTypeName || inputName == BelaAudioIODevice::belaTypeName) return new BelaAudioIODevice(); diff --git a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp index 69b0d6d2..6e9aa954 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp @@ -60,7 +60,16 @@ namespace CoreMidiHelpers SInt32 objectID = 0; if (CHECK_ERROR (MIDIObjectGetIntegerProperty (entity, kMIDIPropertyUniqueID, &objectID))) + { info.identifier = String (objectID); + } + else + { + ScopedCFString str; + + if (CHECK_ERROR (MIDIObjectGetStringProperty (entity, kMIDIPropertyUniqueID, &str.cfString))) + info.identifier = String::fromCFString (str.cfString); + } return info; } @@ -211,9 +220,22 @@ namespace CoreMidiHelpers if (! hasEnabledNetworkSession) { - MIDINetworkSession* session = [MIDINetworkSession defaultSession]; - session.enabled = YES; - session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone; + auto iOSVersion = nsStringToJuce ([[UIDevice currentDevice] systemVersion]); + auto majorVersion = StringArray::fromTokens (iOSVersion, ".", {})[0].getIntValue(); + + if (majorVersion == 13) + { + // From the Xcode 11 release notes known issues: + // Attempting to create an MIDINetworkSession in a simulated device running + // iOS 13 won’t succeed. (54484923) + jassertfalse; + } + else + { + MIDINetworkSession* session = [MIDINetworkSession defaultSession]; + session.enabled = YES; + session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone; + } hasEnabledNetworkSession = true; } @@ -375,7 +397,7 @@ namespace CoreMidiHelpers static Array getEndpoints (bool isInput) { Array endpoints; - auto numDevices = (isInput ? MIDIGetNumberOfSources() : MIDIGetNumberOfDevices()); + auto numDevices = (isInput ? MIDIGetNumberOfSources() : MIDIGetNumberOfDestinations()); for (ItemCount i = 0; i < numDevices; ++i) endpoints.add (isInput ? MIDIGetSource (i) : MIDIGetDestination (i)); diff --git a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp index 039da4af..330b86b2 100644 --- a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp @@ -494,6 +494,9 @@ public: if (status != noErr) return false; + if (numFramesToRead == 0) + break; + if ((int) numFramesToRead < numThisTime) { numThisTime = (int) numFramesToRead; diff --git a/modules/juce_audio_formats/juce_audio_formats.h b/modules/juce_audio_formats/juce_audio_formats.h index 17a85349..179d89f8 100644 --- a/modules/juce_audio_formats/juce_audio_formats.h +++ b/modules/juce_audio_formats/juce_audio_formats.h @@ -35,7 +35,7 @@ ID: juce_audio_formats vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE audio file format codecs description: Classes for reading and writing various audio file formats. website: http://www.juce.com/juce diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp index f6149663..adc374e1 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp @@ -1521,7 +1521,7 @@ namespace AAXClasses : juceParameters.getParamID (audioProcessor, parameterIndex); aaxParamIDs.add (paramID); - auto aaxParamID = aaxParamIDs.getReference (parameterIndex++).getCharPointer(); + auto* aaxParamID = aaxParamIDs.getReference (parameterIndex++).toRawUTF8(); paramMap.set (AAXClasses::getAAXParamHash (aaxParamID), juceParam); @@ -1910,7 +1910,7 @@ namespace AAXClasses inline AAX_CParamID getAAXParamIDFromJuceIndex (int index) const noexcept { if (isPositiveAndBelow (index, aaxParamIDs.size())) - return aaxParamIDs.getReference (index).getCharPointer(); + return aaxParamIDs.getReference (index).toRawUTF8(); return nullptr; } diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h index 9c73eca2..0cc15378 100644 --- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h +++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h @@ -42,7 +42,8 @@ namespace juce @tags{Audio} */ class StandalonePluginHolder : private AudioIODeviceCallback, - private Timer + private Timer, + private Value::Listener { public: //============================================================================== @@ -78,9 +79,11 @@ public: : settings (settingsToUse, takeOwnershipOfSettings), channelConfiguration (channels), - shouldMuteInput (! isInterAppAudioConnected()), autoOpenMidiDevices (shouldAutoOpenMidiDevices) { + shouldMuteInput.addListener (this); + shouldMuteInput = ! isInterAppAudioConnected(); + createPlugin(); auto inChannels = (channelConfiguration.size() > 0 ? channelConfiguration[0].numIns @@ -158,6 +161,7 @@ public: //============================================================================== Value& getMuteInputValue() { return shouldMuteInput; } bool getProcessorHasPotentialFeedbackLoop() const { return processorHasPotentialFeedbackLoop; } + void valueChanged (Value& value) override { muteInput = (bool) value.getValue(); } //============================================================================== File getLastFile() const @@ -406,6 +410,7 @@ public: // avoid feedback loop by default bool processorHasPotentialFeedbackLoop = true; + std::atomic muteInput { true }; Value shouldMuteInput; AudioBuffer emptyBuffer; bool autoOpenMidiDevices; @@ -492,9 +497,7 @@ private: int numOutputChannels, int numSamples) override { - const bool inputMuted = shouldMuteInput.getValue(); - - if (inputMuted) + if (muteInput) { emptyBuffer.clear(); inputChannelData = emptyBuffer.getArrayOfReadPointers(); diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp index 3ede36fa..9b9a7f9f 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -1110,18 +1110,35 @@ public: deleteEditor (true); } - if (chunkMemoryTime > 0 - && chunkMemoryTime < juce::Time::getApproximateMillisecondCounter() - 2000 - && ! recursionCheck) { - chunkMemory.reset(); - chunkMemoryTime = 0; + ScopedLock lock (stateInformationLock); + + if (chunkMemoryTime > 0 + && chunkMemoryTime < juce::Time::getApproximateMillisecondCounter() - 2000 + && ! recursionCheck) + { + chunkMemory.reset(); + chunkMemoryTime = 0; + } } if (editorComp != nullptr) editorComp->checkVisibility(); } + void setHasEditorFlag (bool shouldSetHasEditor) + { + auto hasEditor = (vstEffect.flags & Vst2::effFlagsHasEditor) != 0; + + if (shouldSetHasEditor == hasEditor) + return; + + if (shouldSetHasEditor) + vstEffect.flags |= Vst2::effFlagsHasEditor; + else + vstEffect.flags &= ~Vst2::effFlagsHasEditor; + } + void createEditorComp() { if (hasShutdown || processor == nullptr) @@ -1131,12 +1148,12 @@ public: { if (auto* ed = processor->createEditorIfNeeded()) { - vstEffect.flags |= Vst2::effFlagsHasEditor; + setHasEditorFlag (true); editorComp.reset (new EditorCompWrapper (*this, *ed)); } else { - vstEffect.flags &= ~Vst2::effFlagsHasEditor; + setHasEditorFlag (false); } } @@ -1702,10 +1719,7 @@ private: pointer_sized_int handleOpen (VstOpCodeArguments) { // Note: most hosts call this on the UI thread, but wavelab doesn't, so be careful in here. - if (processor->hasEditor()) - vstEffect.flags |= Vst2::effFlagsHasEditor; - else - vstEffect.flags &= ~Vst2::effFlagsHasEditor; + setHasEditorFlag (processor->hasEditor()); return 0; } @@ -1857,7 +1871,9 @@ private: auto data = (void**) args.ptr; bool onlyStoreCurrentProgramData = (args.index != 0); + ScopedLock lock (stateInformationLock); chunkMemory.reset(); + if (onlyStoreCurrentProgramData) processor->getCurrentProgramStateInformation (chunkMemory); else @@ -1880,15 +1896,19 @@ private: int32 byteSize = (int32) args.value; bool onlyRestoreCurrentProgramData = (args.index != 0); - chunkMemory.reset(); - chunkMemoryTime = 0; - - if (byteSize > 0 && data != nullptr) { - if (onlyRestoreCurrentProgramData) - processor->setCurrentProgramStateInformation (data, byteSize); - else - processor->setStateInformation (data, byteSize); + ScopedLock lock (stateInformationLock); + + chunkMemory.reset(); + chunkMemoryTime = 0; + + if (byteSize > 0 && data != nullptr) + { + if (onlyRestoreCurrentProgramData) + processor->setCurrentProgramStateInformation (data, byteSize); + else + processor->setStateInformation (data, byteSize); + } } } @@ -2272,8 +2292,9 @@ private: double sampleRate = 44100.0; int32 blockSize = 1024; Vst2::AEffect vstEffect; + CriticalSection stateInformationLock; juce::MemoryBlock chunkMemory; - juce::uint32 chunkMemoryTime = 0; + uint32 chunkMemoryTime = 0; std::unique_ptr editorComp; Vst2::ERect editorBounds; MidiBuffer midiEvents; diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index cd06128a..d94d022a 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -319,7 +319,7 @@ private: } //============================================================================== - Atomic refCount; + std::atomic refCount { 0 }; std::unique_ptr audioProcessor; //============================================================================== @@ -469,7 +469,7 @@ public: // Only update the AudioProcessor here if we're not playing, // otherwise we get parallel streams of parameter value updates // during playback - if (owner.vst3IsPlaying.get() == 0) + if (! owner.vst3IsPlaying) { auto value = static_cast (v); @@ -888,7 +888,7 @@ public: / static_cast (pluginInstance->getNumPrograms() - 1)); } - if (componentHandler != nullptr) + if (componentHandler != nullptr && ! inSetupProcessing) componentHandler->restartComponent (Vst::kLatencyChanged | Vst::kParamValuesChanged); } @@ -932,7 +932,9 @@ private: Vst::ParamID midiControllerToParameter[numMIDIChannels][Vst::kCountCtrlNumber]; //============================================================================== - Atomic vst3IsPlaying { 0 }; + std::atomic vst3IsPlaying { false }, + inSetupProcessing { false }; + float lastScaleFactorReceived = 1.0f; void setupParameters() @@ -1197,10 +1199,12 @@ private: { if (auto* constrainer = editor->getConstrainer()) { - auto minW = (double) constrainer->getMinimumWidth(); - auto maxW = (double) constrainer->getMaximumWidth(); - auto minH = (double) constrainer->getMinimumHeight(); - auto maxH = (double) constrainer->getMaximumHeight(); + auto scale = editor->getTransform().getScaleFactor(); + + auto minW = (double) (constrainer->getMinimumWidth() * scale); + auto maxW = (double) (constrainer->getMaximumWidth() * scale); + auto minH = (double) (constrainer->getMinimumHeight() * scale); + auto maxH = (double) (constrainer->getMaximumHeight() * scale); auto width = (double) (rectToCheck->right - rectToCheck->left); auto height = (double) (rectToCheck->bottom - rectToCheck->top); @@ -1460,7 +1464,7 @@ private: #if JUCE_MAC if (host.isWavelab() || host.isReaper()) #else - if (host.isWavelab()) + if (host.isWavelab() || host.isAbletonLive()) #endif setBounds (0, 0, w, h); } @@ -1578,7 +1582,7 @@ public: ~JuceVST3Component() override { if (juceVST3EditController != nullptr) - juceVST3EditController->vst3IsPlaying = 0; + juceVST3EditController->vst3IsPlaying = false; if (pluginInstance != nullptr) if (pluginInstance->getPlayHead() == this) @@ -1644,7 +1648,7 @@ public: tresult PLUGIN_API disconnect (IConnectionPoint*) override { if (juceVST3EditController != nullptr) - juceVST3EditController->vst3IsPlaying = 0; + juceVST3EditController->vst3IsPlaying = false; juceVST3EditController = nullptr; return kResultTrue; @@ -2350,6 +2354,8 @@ public: tresult PLUGIN_API setupProcessing (Vst::ProcessSetup& newSetup) override { + ScopedInSetupProcessingSetter inSetupProcessingSetter (juceVST3EditController); + if (canProcessSampleSize (newSetup.symbolicSampleSize) != kResultTrue) return kResultFalse; @@ -2470,14 +2476,14 @@ public: processContext = *data.processContext; if (juceVST3EditController != nullptr) - juceVST3EditController->vst3IsPlaying = processContext.state & Vst::ProcessContext::kPlaying; + juceVST3EditController->vst3IsPlaying = (processContext.state & Vst::ProcessContext::kPlaying) != 0; } else { zerostruct (processContext); if (juceVST3EditController != nullptr) - juceVST3EditController->vst3IsPlaying = 0; + juceVST3EditController->vst3IsPlaying = false; } midiBuffer.clear(); @@ -2513,6 +2519,26 @@ public: } private: + //============================================================================== + struct ScopedInSetupProcessingSetter + { + ScopedInSetupProcessingSetter (JuceVST3EditController* c) + : controller (c) + { + if (controller != nullptr) + controller->inSetupProcessing = true; + } + + ~ScopedInSetupProcessingSetter() + { + if (controller != nullptr) + controller->inSetupProcessing = false; + } + + private: + JuceVST3EditController* controller = nullptr; + }; + //============================================================================== template void processAudio (Vst::ProcessData& data, Array& channelList) @@ -2732,7 +2758,7 @@ private: //============================================================================== ScopedJuceInitialiser_GUI libraryInitialiser; - Atomic refCount { 1 }; + std::atomic refCount { 1 }; AudioProcessor* pluginInstance; ComSmartPtr host; @@ -3049,7 +3075,7 @@ struct JucePluginFactory : public IPluginFactory3 private: //============================================================================== - Atomic refCount { 1 }; + std::atomic refCount { 1 }; const PFactoryInfo factoryInfo; ComSmartPtr host; diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client.h b/modules/juce_audio_plugin_client/juce_audio_plugin_client.h index 4988e5b6..d884d0ac 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client.h +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client.h @@ -35,7 +35,7 @@ ID: juce_audio_plugin_client vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE audio plugin wrapper classes description: Classes for building VST, VST3, AudioUnit, AAX and RTAS plugins. website: http://www.juce.com/juce diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index af6e491b..33974d48 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -1213,8 +1213,11 @@ public: if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, &presets, &sz) == noErr) { - num = (int) CFArrayGetCount (presets); - CFRelease (presets); + if (presets != nullptr) + { + num = (int) CFArrayGetCount (presets); + CFRelease (presets); + } } return num; diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 63b95b97..14810fb5 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -189,8 +189,8 @@ static void toProcessContext (Vst::ProcessContext& context, AudioPlayHead* playH AudioPlayHead::CurrentPositionInfo position; playHead->getCurrentPosition (position); - context.projectTimeSamples = position.timeInSamples; //Must always be valid, as stated by the VST3 SDK - context.projectTimeMusic = position.timeInSeconds; //Does not always need to be valid... + context.projectTimeSamples = position.timeInSamples; // Must always be valid, as stated by the VST3 SDK + context.projectTimeMusic = position.ppqPosition; // Does not always need to be valid... context.tempo = position.bpm; context.timeSigNumerator = position.timeSigNumerator; context.timeSigDenominator = position.timeSigDenominator; diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 35293b8b..85dfb785 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2796,7 +2796,11 @@ public: Vst2::ERect* rect = nullptr; dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); - setSize (rect->right - rect->left, rect->bottom - rect->top); + + if (rect != nullptr) + setSize (rect->right - rect->left, rect->bottom - rect->top); + else + setSize (1, 1); setOpaque (true); setVisible (true); diff --git a/modules/juce_audio_processors/juce_audio_processors.h b/modules/juce_audio_processors/juce_audio_processors.h index cb46f60c..62b0f498 100644 --- a/modules/juce_audio_processors/juce_audio_processors.h +++ b/modules/juce_audio_processors/juce_audio_processors.h @@ -35,7 +35,7 @@ ID: juce_audio_processors vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE audio processor classes description: Classes for loading and playing VST, AU, LADSPA, or internally-generated audio processors. website: http://www.juce.com/juce diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index f36e3553..04a11a92 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1011,7 +1011,7 @@ public: /** Returns the group of parameters managed by this AudioProcessor. */ const AudioProcessorParameterGroup& getParameterTree() const; - /** Returns the group of parameters managed by this AudioProcessor. */ + /** Sets the group of parameters managed by this AudioProcessor. */ void setParameterTree (AudioProcessorParameterGroup&& newTree); /** A processor should implement this method so that the host can ask it to diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index 1fb8a495..f7ce5789 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -162,6 +162,7 @@ public: struct JUCE_API Connection { //============================================================================== + Connection() = default; Connection (NodeAndChannel source, NodeAndChannel destination) noexcept; Connection (const Connection&) = default; @@ -173,10 +174,10 @@ public: //============================================================================== /** The channel and node which is the input source for this connection. */ - NodeAndChannel source; + NodeAndChannel source { {}, 0 }; /** The channel and node which is the input source for this connection. */ - NodeAndChannel destination; + NodeAndChannel destination { {}, 0 }; }; //============================================================================== diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h index 0981e119..23714e2b 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h @@ -42,7 +42,7 @@ public: */ AudioProcessorParameterWithID (const String& parameterID, const String& parameterName, - const String& parameterLabel = String(), + const String& parameterLabel = {}, Category parameterCategory = AudioProcessorParameter::genericParameter); /** Destructor. */ @@ -60,11 +60,11 @@ public: /** Provides access to the parameter's category. */ const Category category; -private: String getName (int) const override; String getLabel() const override; Category getCategory() const override; +private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameterWithID) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index 681d3e0f..ad36c5aa 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -71,7 +71,9 @@ void AudioProcessorValueTreeState::Parameter::valueChanged (float newValue) return; lastValue = newValue; - sendValueChangedMessageToListeners (newValue); + + if (onValueChanged != nullptr) + onValueChanged(); } //============================================================================== @@ -87,6 +89,9 @@ public: unnormalisedValue (getRange().convertFrom0to1 (parameter.getDefaultValue())) { parameter.addListener (this); + + if (auto* ptr = dynamic_cast (¶meter)) + ptr->onValueChanged = [this] { parameterValueChanged ({}, {}); }; } ~ParameterAdapter() override { parameter.removeListener (this); } diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h index a0cc2b0e..f1ee8a43 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h @@ -362,6 +362,10 @@ public: UndoManager* const undoManager; //============================================================================== +private: + class ParameterAdapter; + +public: /** A parameter class that maintains backwards compatibility with deprecated AudioProcessorValueTreeState functionality. @@ -416,9 +420,13 @@ public: private: void valueChanged (float) override; + std::function onValueChanged; + const float unsnappedDefault; const bool metaParameter, automatable, discrete, boolean; - float lastValue = 0.0f; + float lastValue = -1.0f; + + friend class AudioProcessorValueTreeState::ParameterAdapter; }; //============================================================================== @@ -523,8 +531,6 @@ private: bool, bool, bool, AudioProcessorParameter::Category, bool)); //============================================================================== - class ParameterAdapter; - #if JUCE_UNIT_TESTS friend struct ParameterAdapterTests; #endif diff --git a/modules/juce_audio_utils/gui/juce_AudioAppComponent.h b/modules/juce_audio_utils/gui/juce_AudioAppComponent.h index 02bd03b0..30363206 100644 --- a/modules/juce_audio_utils/gui/juce_AudioAppComponent.h +++ b/modules/juce_audio_utils/gui/juce_AudioAppComponent.h @@ -125,7 +125,7 @@ public: AudioDeviceManager& deviceManager; private: - //============================================================================= + //============================================================================== AudioDeviceManager defaultDeviceManager; AudioSourcePlayer audioSourcePlayer; bool usingCustomDeviceManager; diff --git a/modules/juce_audio_utils/juce_audio_utils.h b/modules/juce_audio_utils/juce_audio_utils.h index 72adf9a2..e346c70b 100644 --- a/modules/juce_audio_utils/juce_audio_utils.h +++ b/modules/juce_audio_utils/juce_audio_utils.h @@ -35,7 +35,7 @@ ID: juce_audio_utils vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE extra audio utility classes description: Classes for audio-related GUI and miscellaneous tasks. website: http://www.juce.com/juce diff --git a/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm b/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm index eccb0b82..2b564aa1 100644 --- a/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm +++ b/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm @@ -51,7 +51,7 @@ public: setBounds (bounds); toFront (true); - setOpaque (! bounds.isEmpty()); + setOpaque (true); controller = [[CABTMIDICentralViewController alloc] init]; nativeSelectorComponent.setView ([controller view]); diff --git a/modules/juce_blocks_basics/blocks/juce_Block.h b/modules/juce_blocks_basics/blocks/juce_Block.h index eddc0b9a..41def683 100644 --- a/modules/juce_blocks_basics/blocks/juce_Block.h +++ b/modules/juce_blocks_basics/blocks/juce_Block.h @@ -320,7 +320,7 @@ public: /** Metadata for a given config item */ struct ConfigMetaData { - static constexpr int32 numOptionNames = 8; + static constexpr int32 numOptionNames = 16; enum class ConfigType { diff --git a/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h b/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h index 0b288c6f..e93e5857 100644 --- a/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h +++ b/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h @@ -47,7 +47,7 @@ struct BlockConfigManager void setDeviceIndex (TopologyIndex newDeviceIndex) { deviceIndex = newDeviceIndex; } void setDeviceComms (PhysicalTopologySource::DeviceConnection* newConn) { deviceConnection = newConn; } - static constexpr uint32 numConfigItems = 64; + static constexpr uint32 numConfigItems = 69; /** Structure describing a configuration */ struct ConfigDescription @@ -100,10 +100,17 @@ struct BlockConfigManager { mode, 4, 1, 5, false, "Mode", ConfigType::integer, {}, "Play mode" }, { volume, 100, 0, 127, false, "Volume", ConfigType::integer, {}, "Play mode" }, { scale, 0, 0, 18, false, "Scale", ConfigType::integer, {}, "Play mode" }, // NOTE: Should be options + { key, 0, 0, 11, false, "Key", ConfigType::options, { "C", "C#", "D", "D#", + "E", "F", "F#", "G", + "G#", "A", "A#", "B"}, "Play mode" }, { hideMode, 0, 0, 1, false, "Hide Mode", ConfigType::boolean, {}, "Play mode" }, { chord, 0, 0, 127, false, "Chord", ConfigType::integer, {}, "Play mode" }, // NOTE: Should be options { arpPattern, 0, 0, 127, false, "Arp Pattern", ConfigType::integer, {}, "Play mode" }, { tempo, 120, 1, 300, false, "Tempo", ConfigType::integer, {}, "Rhythm" }, + { key, 0, 0, 11, false, "Key", ConfigType::options, { "C", "C#", "D", "D#", + "E", "F", "F#", "G", + "G#", "A", "A#", "B"}, "Play mode" }, + { autoTransposeToKey, 0, 0, 1, false, "Auto Transpose To Key",ConfigType::boolean, {}, "Pitch" }, { xTrackingMode, 1, 1, 4, false, "Glide Tracking Mode", ConfigType::options, { "Multi-Channel", "Last Played", "Highest", @@ -122,6 +129,9 @@ struct BlockConfigManager "Hardest" }, "Play mode" }, { gammaCorrection, 0, 0, 1, false, "Gamma Correction", ConfigType::boolean, {}, {} }, + { globalKeyColour, INT32_MIN, INT32_MIN, INT32_MAX, false, "Global Key Colour", ConfigType::colour, {}, "Colour" }, + { rootKeyColour, INT32_MIN, INT32_MIN, INT32_MAX, false, "Root Key Colour" , ConfigType::colour, {}, "Colour" }, + { brightness, 100, 0, 100, false, "Brightness", ConfigType::integer, {}, "Colour" }, // These can be defined for unique usage for a given Littlefoot script { user0, 0, 0, 127, false, {}, ConfigType::integer, {}, {} }, diff --git a/modules/juce_blocks_basics/blocks/juce_TouchList.h b/modules/juce_blocks_basics/blocks/juce_TouchList.h index 2b99311d..5f7287d9 100644 --- a/modules/juce_blocks_basics/blocks/juce_TouchList.h +++ b/modules/juce_blocks_basics/blocks/juce_TouchList.h @@ -137,7 +137,7 @@ public: void clear() noexcept { touches.clear(); } private: - //========================================================================== + //============================================================================== static bool matches (const TouchSurface::Touch& t1, const TouchSurface::Touch& t2) noexcept { diff --git a/modules/juce_blocks_basics/juce_blocks_basics.h b/modules/juce_blocks_basics/juce_blocks_basics.h index 5ae9a83b..aa8f3396 100644 --- a/modules/juce_blocks_basics/juce_blocks_basics.h +++ b/modules/juce_blocks_basics/juce_blocks_basics.h @@ -31,7 +31,7 @@ ID: juce_blocks_basics vendor: juce - version: 5.4.4 + version: 5.4.5 name: Provides low-level control over ROLI BLOCKS devices description: JUCE wrapper for low-level control over ROLI BLOCKS devices. website: http://developer.roli.com diff --git a/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h b/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h index c124ecd0..04524479 100644 --- a/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h +++ b/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h @@ -19,8 +19,15 @@ ============================================================================== */ +#ifndef JUCE_DUMP_LITTLEFOOT_HEAP_STATUS + #define JUCE_DUMP_LITTLEFOOT_HEAP_STATUS 0 +#endif -#define JUCE_DUMP_LITTLEFOOT_HEAP_STATUS 0 +#if JUCE_DUMP_LITTLEFOOT_HEAP_STATUS + #define JUCE_LOG_LITTLEFOOT_HEAP(text) DBG(text) +#else + #define JUCE_LOG_LITTLEFOOT_HEAP(text) +#endif namespace littlefoot { @@ -43,15 +50,27 @@ struct LittleFootRemoteHeap resetDeviceStateToUnknown(); } - void clear() noexcept + void reset() { + JUCE_LOG_LITTLEFOOT_HEAP ("Resetting heap state"); + clearTargetData(); + resetDeviceStateToUnknown(); + lastPacketIndexReceived = 0; + } + + void clearTargetData() noexcept + { + JUCE_LOG_LITTLEFOOT_HEAP ("Clearing target heap data"); zeromem (targetData, sizeof (targetData)); - invalidateData(); + needsSyncing = true; + programStateKnown = false; } void resetDeviceStateToUnknown() { - invalidateData(); + JUCE_LOG_LITTLEFOOT_HEAP ("Resetting device state to unknown"); + needsSyncing = true; + programStateKnown = false; messagesSent.clear(); resetDataRangeToUnknown (0, ImplementationClass::maxBlockSize); } @@ -66,20 +85,19 @@ struct LittleFootRemoteHeap void setByte (size_t offset, uint8 value) noexcept { - if (offset < blockSize) + if (offset >= blockSize) { - if (targetData[offset] != value) - { - targetData[offset] = value; - needsSyncing = true; - - if (programStateKnown && offset < programSize) - programStateKnown = false; - } + jassertfalse; + return; } - else + + if (targetData[offset] != value) { - jassertfalse; + targetData[offset] = value; + needsSyncing = true; + + if (offset < programSize) + programStateKnown = false; } } @@ -99,8 +117,14 @@ struct LittleFootRemoteHeap if (readLittleEndianBitsInBuffer (targetData, startBit, numBits) != value) { + JUCE_LOG_LITTLEFOOT_HEAP ("Set bits sync " << String (startBit) << " " << String (numBits) << String (value)); + writeLittleEndianBitsInBuffer (targetData, startBit, numBits, value); - invalidateData(); + + needsSyncing = true; + + if (startBit < programSize) + programStateKnown = false; } } @@ -113,12 +137,6 @@ struct LittleFootRemoteHeap return 0; } - void invalidateData() noexcept - { - needsSyncing = true; - programStateKnown = false; - } - bool isFullySynced() const noexcept { return ! needsSyncing; @@ -167,7 +185,8 @@ struct LittleFootRemoteHeap m->dispatchTime = Time::getCurrentTime(); bi.sendMessageToDevice (m->packet); - //DBG ("Sending packet " << (int) m->packetIndex << " - " << m->packet.size() << " bytes, device " << bi.getDeviceIndex()); + + JUCE_LOG_LITTLEFOOT_HEAP ("Sending packet " << (int) m->packetIndex << " - " << m->packet.size() << " bytes, device " << bi.getDeviceIndex()); if (getTotalSizeOfMessagesSent() > 200) break; @@ -176,43 +195,45 @@ struct LittleFootRemoteHeap void handleACKFromDevice (ImplementationClass& bi, uint32 packetIndex) noexcept { - //DBG ("ACK " << (int) packetIndex << " device " << (int) bi.getDeviceIndex()); + if (packetIndex == lastPacketIndexReceived) + return; - if (lastPacketIndexReceived != packetIndex) - { - lastPacketIndexReceived = packetIndex; + JUCE_LOG_LITTLEFOOT_HEAP ("ACK " << (int) packetIndex << " device " << (int) bi.getDeviceIndex() + << ", last packet received " << String (lastPacketIndexReceived)); - for (int i = messagesSent.size(); --i >= 0;) - { - auto& m = *messagesSent.getUnchecked(i); + lastPacketIndexReceived = packetIndex; - if (m.packetIndex == packetIndex) - { - for (uint32 j = 0; j < blockSize; ++j) - deviceState[j] = m.resultDataState[j]; + for (int i = messagesSent.size(); --i >= 0;) + { + auto& m = *messagesSent.getUnchecked(i); - programStateKnown = false; - messagesSent.removeRange (0, i + 1); - dumpStatus(); - sendChanges (bi, false); + if (m.packetIndex == packetIndex) + { + for (uint32 j = 0; j < blockSize; ++j) + deviceState[j] = m.resultDataState[j]; - if (messagesSent.isEmpty()) - needsSyncing = false; + programStateKnown = false; + messagesSent.removeRange (0, i + 1); + dumpStatus(); + sendChanges (bi, false); - return; + if (messagesSent.isEmpty()) + { + JUCE_LOG_LITTLEFOOT_HEAP ("Heap fully synced"); + needsSyncing = false; } - } - resetDeviceStateToUnknown(); + return; + } } + + resetDeviceStateToUnknown(); } bool isProgramLoaded() noexcept { if (! programStateKnown) { - programStateKnown = true; - uint8 deviceMemory[ImplementationClass::maxBlockSize]; for (size_t i = 0; i < blockSize; ++i) @@ -221,6 +242,8 @@ struct LittleFootRemoteHeap littlefoot::Program prog (deviceMemory, (uint32) blockSize); programLoaded = prog.checksumMatches(); programSize = prog.getProgramSize(); + + programStateKnown = true; } return programLoaded; @@ -287,8 +310,8 @@ private: ignoreUnused (proportionOK); - DBG ("Heap: " << areas << " " << String (roundToInt (100 * proportionOK)) << "% " - << (isProgramLoaded() ? "Ready" : "Loading")); + JUCE_LOG_LITTLEFOOT_HEAP ("Heap: " << areas << " " << String (roundToInt (100 * proportionOK)) + << "% " << (isProgramLoaded() ? "Ready" : "Loading")); #endif } diff --git a/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h b/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h index 4a38c416..b2399d50 100644 --- a/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h +++ b/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h @@ -303,12 +303,17 @@ enum ConfigItemId chord = 24, arpPattern = 25, tempo = 26, + key = 27, + autoTransposeToKey = 28, // Tracking xTrackingMode = 30, yTrackingMode = 31, zTrackingMode = 32, // Graphics gammaCorrection = 33, + globalKeyColour = 34, + rootKeyColour = 35, + brightness = 36, // User user0 = 64, user1 = 65, @@ -348,7 +353,7 @@ static constexpr uint8 numberOfUserConfigs = 32; static constexpr uint8 maxConfigIndex = uint8 (ConfigItemId::user0) + numberOfUserConfigs; static constexpr uint8 configUserConfigNameLength = 32; -static constexpr uint8 configMaxOptions = 8; +static constexpr uint8 configMaxOptions = 16; static constexpr uint8 configOptionNameLength = 16; //============================================================================== @@ -591,6 +596,14 @@ static constexpr const char* ledProgramLittleFootFunctions[] = "setButtonMinMaxDefault/viiii", "setButtonColours/viii", "setButtonTriState/vii", + "padControllerInitDefault/vb", + "padControllerReset/v", + "padControllerRegenDefault/v", + "padControllerRepaint/v", + "padControllerDrawPad/vi", + "setUseDefaultKeyHandler/vb", + "setUseDefaultKeyHandler/vbb", + nullptr }; diff --git a/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp b/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp index f7f581c1..6d3a7fbd 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp @@ -83,16 +83,11 @@ public: if (connectionTime == Time()) connectionTime = Time::getCurrentTime(); - versionNumber = deviceInfo.version.asString(); - name = deviceInfo.name.asString(); - isMaster = deviceInfo.isMaster; - masterUID = deviceInfo.masterUid; - batteryCharging = deviceInfo.batteryCharging; - batteryLevel = deviceInfo.batteryLevel; - topologyIndex = deviceInfo.index; + updateDeviceInfo (deviceInfo); + + remoteHeap.reset(); setProgram (nullptr); - remoteHeap.resetDeviceStateToUnknown(); if (auto surface = dynamic_cast (touchSurface.get())) surface->activateTouchSurface(); @@ -100,6 +95,17 @@ public: updateMidiConnectionListener(); } + void updateDeviceInfo (const DeviceInfo& deviceInfo) + { + versionNumber = deviceInfo.version.asString(); + name = deviceInfo.name.asString(); + isMaster = deviceInfo.isMaster; + masterUID = deviceInfo.masterUid; + batteryCharging = deviceInfo.batteryCharging; + batteryLevel = deviceInfo.batteryLevel; + topologyIndex = deviceInfo.index; + } + void setToMaster (bool shouldBeMaster) { isMaster = shouldBeMaster; @@ -289,7 +295,7 @@ public: if (program == nullptr) { - remoteHeap.clear(); + remoteHeap.clearTargetData(); return Result::ok(); } @@ -311,7 +317,7 @@ public: programSize = (uint32) size; remoteHeap.resetDataRangeToUnknown (0, remoteHeap.blockSize); - remoteHeap.clear(); + remoteHeap.clearTargetData(); remoteHeap.sendChanges (*this, true); remoteHeap.resetDataRangeToUnknown (0, (uint32) size); @@ -504,10 +510,15 @@ public: remoteHeap.sendChanges (*this, false); - if (lastMessageSendTime < Time::getCurrentTime() - RelativeTime::milliseconds (pingIntervalMs)) + if (lastMessageSendTime < Time::getCurrentTime() - getPingInterval()) sendCommandMessage (BlocksProtocol::ping); } + RelativeTime getPingInterval() + { + return RelativeTime::milliseconds (isMaster ? masterPingIntervalMs : dnaPingIntervalMs); + } + //============================================================================== int32 getLocalConfigValue (uint32 item) override { @@ -629,7 +640,8 @@ public: MIDIDeviceConnection* listenerToMidiConnection = nullptr; - static constexpr int pingIntervalMs = 400; + static constexpr int masterPingIntervalMs = 400; + static constexpr int dnaPingIntervalMs = 1666; static constexpr uint32 maxBlockSize = BlocksProtocol::padBlockProgramAndHeapSize; static constexpr uint32 maxPacketCounter = BlocksProtocol::PacketCounter::maxValue; diff --git a/modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp b/modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp new file mode 100644 index 00000000..c4a94e92 --- /dev/null +++ b/modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp @@ -0,0 +1,130 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2019 - ROLI Ltd. + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + class BlockSerialReader + : private MIDIDeviceConnection::Listener, + private Timer + { + public: + //============================================================================== + BlockSerialReader (MIDIDeviceConnection& deviceConnectionToUse) : deviceConnection (deviceConnectionToUse) + { + deviceConnection.addListener (this); + startTimer (10); + } + + ~BlockSerialReader() override + { + deviceConnection.removeListener (this); + } + + bool hasSerial() const { return serial.isNotEmpty(); } + + String getSerial() const { return serial; } + + private: + MIDIDeviceConnection& deviceConnection; + String serial; + + bool shouldStop() { return hasSerial(); } + + //============================================================================== + void timerCallback() override + { + if (shouldStop()) + { + stopTimer(); + return; + } + + sendRequest(); + startTimer (300); + } + + void sendRequest() + { + const uint8 dumpRequest[] = { 0xf0, 0x00, 0x21, 0x10, 0x78, 0x3f, 0xf7 }; + deviceConnection.sendMessageToDevice (dumpRequest, sizeof (dumpRequest)); + } + + void handleIncomingMidiMessage (const MidiMessage& message) override + { + if (hasSerial()) + return; + + if (isResponse (message)) + parseResponse (message); + } + + void connectionBeingDeleted (const MIDIDeviceConnection&) override + { + stopTimer(); + } + + bool isResponse (const MidiMessage message) + { + const uint8 roliDumpHeader[] = { 0xf0, 0x00, 0x21, 0x10, 0x78}; + return memcmp (message.getRawData(), roliDumpHeader, sizeof (roliDumpHeader)) == 0; + } + + void parseResponse (const MidiMessage& message) + { + int index = findMacAddressStart (message); + + if (index >= 0) + { + const int macSize = 17; + const int offset = index + macSize; + const int serialSize = 16; + + if (message.getRawDataSize() - offset < serialSize) + { + jassertfalse; + return; + } + + serial = String ((const char*)message.getRawData() + offset, serialSize); + } + } + + int findMacAddressStart (const MidiMessage& message) + { + const uint8 macStart[] = { '4', '8', ':', 'B', '6', ':', '2', '0', ':' }; + return findSequence (macStart, sizeof (macStart), message); + } + + int findSequence (const uint8* sequence, int sequenceSize, const MidiMessage& message) + { + for (int i = 0; i < message.getRawDataSize() - sequenceSize; i++) + { + if (memcmp (message.getRawData() + i, sequence, size_t (sequenceSize)) == 0) + return i; + } + + return -1; + } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlockSerialReader) + }; +} diff --git a/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp b/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp index cab84e88..5d4c8615 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp @@ -49,6 +49,8 @@ struct ConnectedDeviceGroup : private AsyncUpdater, setMidiMessageCallback(); } + initialiseSerialReader(); + startTimer (200); sendTopologyRequest(); } @@ -294,12 +296,13 @@ private: Array incomingPackets; std::unique_ptr depreciatedVersionReader; + std::unique_ptr masterSerialReader; struct TouchStart { float x, y; }; TouchList touchStartPositions; static constexpr Block::UID invalidUid = 0; - Block::UID masterBlock = invalidUid; + Block::UID masterBlockUid = invalidUid; //============================================================================== void timerCallback() override @@ -313,7 +316,8 @@ private: checkApiTimeouts (now); startApiModeOnConnectedBlocks(); - requestMasterBlockVersionIfNeeded(); + checkMasterBlockVersion(); + checkMasterSerial(); } //============================================================================== @@ -394,7 +398,7 @@ private: } //============================================================================== - void requestMasterBlockVersionIfNeeded() + void checkMasterBlockVersion() { if (depreciatedVersionReader == nullptr) return; @@ -403,7 +407,7 @@ private: if (masterVersion.isNotEmpty()) { - const auto masterIndex = getIndexFromDeviceID (masterBlock); + const auto masterIndex = getIndexFromDeviceID (masterBlockUid); if (masterIndex >= 0) setVersion (BlocksProtocol::TopologyIndex (masterIndex), masterVersion); @@ -422,7 +426,7 @@ private: if (info->version == versionNumber) return; - if (info->uid == masterBlock) + if (info->uid == masterBlockUid) depreciatedVersionReader.reset(); info->version = versionNumber; @@ -430,6 +434,72 @@ private: } } + //============================================================================== + void checkMasterSerial() + { + if (masterSerialReader == nullptr) + initialiseSerialReader(); + + if (masterSerialReader == nullptr) + return; + + if (masterBlockUid != invalidUid && masterSerialReader->hasSerial()) + { + auto uid = getBlockUIDFromSerialNumber (masterSerialReader->getSerial()); + + if (uid != masterBlockUid) + updateMasterUid (uid); + } + } + + void updateMasterUid (const Block::UID newMasterUid) + { + LOG_CONNECTIVITY ("Updating master from " + String (masterBlockUid) + " to " + String (newMasterUid)); + + masterBlockUid = newMasterUid; + + Array devicesToUpdate; + + for (auto& info : currentDeviceInfo) + { + if (info.masterUid != masterBlockUid) + { + info.masterUid = masterBlockUid; + + info.isMaster = info.uid == masterBlockUid; + + devicesToUpdate.add (info); + } + } + + detector.handleDevicesUpdated (devicesToUpdate); + } + + Block::UID determineMasterBlockUid (Array devices) + { + if (masterSerialReader != nullptr && masterSerialReader->hasSerial()) + { + auto foundSerial = masterSerialReader->getSerial(); + for (const auto& device : incomingTopologyDevices) + { + if (device.serialNumber.asString() == foundSerial) + { + LOG_CONNECTIVITY ("Found master from serial " + foundSerial); + return getBlockUIDFromSerialNumber (foundSerial); + } + } + } + + if (devices.size() > 0) + { + LOG_CONNECTIVITY ("Found master from first device " + devices[0].serialNumber.asString()); + return getBlockUIDFromSerialNumber (incomingTopologyDevices[0].serialNumber); + } + + jassertfalse; + return invalidUid; + } + //============================================================================== struct BlockPingTime { @@ -491,15 +561,16 @@ private: void forceApiDisconnected (Block::UID uid) { - Array toRemove; - for (auto dependentUID : detector.getDnaDependentDeviceUIDs (uid)) removeDevice (dependentUID); removeDevice (uid); - if (uid == masterBlock) - masterBlock = invalidUid; + if (uid == masterBlockUid) + { + masterBlockUid = invalidUid; + masterSerialReader.reset(); + } scheduleNewTopologyRequest(); } @@ -637,22 +708,19 @@ private: for (const auto& uid : toRemove) removeDevice (uid); + if (masterBlockUid == invalidUid) + { + masterBlockUid = determineMasterBlockUid (incomingTopologyDevices); + initialiseVersionReader(); + } + //Add new devices for (const auto& device : incomingTopologyDevices) { const auto uid = getBlockUIDFromSerialNumber (device.serialNumber); - if (! getDeviceInfoFromUID (uid)) + if (getDeviceInfoFromUID (uid) == nullptr) { - // For backwards compatibility we assume the first device we see in a group is the master and won't change - if (masterBlock == invalidUid) - { - masterBlock = uid; - - if (auto midiDeviceConnection = static_cast (deviceConnection.get())) - depreciatedVersionReader = std::make_unique (*midiDeviceConnection); - } - currentDeviceInfo.add ({ uid, device.index, device.serialNumber, @@ -660,7 +728,7 @@ private: BlocksProtocol::BlockName(), device.batteryLevel, device.batteryCharging, - masterBlock }); + masterBlockUid }); } } } @@ -699,6 +767,18 @@ private: detector.handleConnectionsChanged(); } + void initialiseVersionReader() + { + if (auto midiDeviceConnection = static_cast (deviceConnection.get())) + depreciatedVersionReader = std::make_unique (*midiDeviceConnection); + } + + void initialiseSerialReader() + { + if (auto midiDeviceConnection = static_cast (deviceConnection.get())) + masterSerialReader = std::make_unique (*midiDeviceConnection); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectedDeviceGroup) }; diff --git a/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp b/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp index 1fb6c692..09bffab6 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp @@ -177,27 +177,41 @@ struct Detector : public ReferenceCountedObject, triggerAsyncUpdate(); } - void handleDeviceUpdated (const DeviceInfo& info) + void handleDevicesUpdated (const Array& infos) { - if (containsBlockWithUID (blocksToRemove, info.uid)) - return; + bool shouldTriggerUpdate { false }; - const auto blockIt = std::find_if (currentTopology.blocks.begin(), currentTopology.blocks.end(), - [uid = info.uid] (Block::Ptr block) { return uid == block->uid; }); - - if (blockIt != currentTopology.blocks.end()) + for (auto& info : infos) { - const Block::Ptr block { *blockIt }; + if (containsBlockWithUID (blocksToRemove, info.uid)) + continue; + + const auto blockIt = std::find_if (currentTopology.blocks.begin(), currentTopology.blocks.end(), + [uid = info.uid] (Block::Ptr block) { return uid == block->uid; }); - if (auto blockImpl = BlockImpl::getFrom (block.get())) - blockImpl->markReconnected (info); - if (! containsBlockWithUID (blocksToAdd, info.uid)) + if (blockIt != currentTopology.blocks.end()) { - blocksToUpdate.addIfNotAlreadyThere (block); - triggerAsyncUpdate(); + const Block::Ptr block { *blockIt }; + + if (auto blockImpl = BlockImpl::getFrom (block.get())) + blockImpl->updateDeviceInfo (info); + + if (! containsBlockWithUID (blocksToAdd, info.uid)) + { + blocksToUpdate.addIfNotAlreadyThere (block); + shouldTriggerUpdate = true; + } } } + + if (shouldTriggerUpdate) + triggerAsyncUpdate(); + } + + void handleDeviceUpdated (const DeviceInfo& info) + { + handleDevicesUpdated ({ info }); } void handleBatteryChargingChanged (Block::UID deviceID, const BlocksProtocol::BatteryCharging isCharging) diff --git a/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp b/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp index b2297cef..eab5583f 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp @@ -47,13 +47,24 @@ struct PhysicalTopologySource::DetectorHolder : private Timer void handleTimerTick() { - for (auto& b : detector->currentTopology.blocks) - if (auto bi = BlockImplementation::getFrom (*b)) - bi->handleTimerTick(); + auto blocks = detector->currentTopology.blocks; + + if (blocks.size() == 0) + return; + + if (nextIndexToTick >= blocks.size()) + nextIndexToTick = 0; + + if (auto* bi = BlockImplementation::getFrom (*blocks [nextIndexToTick])) + bi->handleTimerTick(); + + nextIndexToTick = (nextIndexToTick + 1) % blocks.size(); } PhysicalTopologySource& topologySource; Detector::Ptr detector; + + int nextIndexToTick {0}; }; } // namespace juce diff --git a/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp b/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp index 56fb9e34..6861db66 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp @@ -67,7 +67,7 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection, { JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED // This method must only be called from the message thread! - jassert (dataSize > sizeof (BlocksProtocol::roliSysexHeader) + 2); + jassert (dataSize > sizeof (BlocksProtocol::roliSysexHeader) + 1); jassert (memcmp (data, BlocksProtocol::roliSysexHeader, sizeof (BlocksProtocol::roliSysexHeader) - 1) == 0); jassert (static_cast (data)[dataSize - 1] == 0xf7); diff --git a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp index 521473e0..e08d54b8 100644 --- a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp +++ b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp @@ -22,10 +22,22 @@ //============================================================================== /** These can be useful when debugging the topology. */ -#define LOG_BLOCKS_CONNECTIVITY 0 -#define LOG_BLOCKS_PINGS 0 -#define DUMP_BANDWIDTH_STATS 0 -#define DUMP_TOPOLOGY 0 + +#ifndef LOG_BLOCKS_CONNECTIVITY + #define LOG_BLOCKS_CONNECTIVITY 0 +#endif + +#ifndef LOG_BLOCKS_PINGS + #define LOG_BLOCKS_PINGS 0 +#endif + +#ifndef DUMP_BANDWIDTH_STATS + #define DUMP_BANDWIDTH_STATS 0 +#endif + +#ifndef DUMP_TOPOLOGY + #define DUMP_TOPOLOGY 0 +#endif #define TOPOLOGY_LOG(text) \ JUCE_BLOCK_WITH_FORCED_SEMICOLON (juce::String buf ("Topology Src: "); \ @@ -51,6 +63,7 @@ #include "internal/juce_MIDIDeviceDetector.cpp" #include "internal/juce_DeviceInfo.cpp" #include "internal/juce_DepreciatedVersionReader.cpp" +#include "internal/juce_BlockSerialReader.cpp" #include "internal/juce_ConnectedDeviceGroup.cpp" #include "internal/juce_BlockImplementation.cpp" #include "internal/juce_Detector.cpp" diff --git a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h index 390bf327..fa1be412 100644 --- a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h +++ b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h @@ -54,7 +54,7 @@ public: /** This method will tell, if an other PhysicalTopologySource has locked the Midi connection */ bool isLockedFromOutside() const; - //========================================================================== + //============================================================================== /** For custom transport systems, this represents a connected device */ struct DeviceConnection { @@ -86,7 +86,7 @@ protected: virtual void handleTimerTick(); private: - //========================================================================== + //============================================================================== DeviceDetector* customDetector = nullptr; friend struct Detector; struct DetectorHolder; diff --git a/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h b/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h index fb7e02d2..1e6baffb 100644 --- a/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h +++ b/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h @@ -43,7 +43,7 @@ public: /** Destructor. */ ~RuleBasedTopologySource() override; - //========================================================================== + //============================================================================== /** Returns the currently active topology. */ BlockTopology getCurrentTopology() const override; @@ -80,7 +80,7 @@ public: bool isActive() const override; private: - //========================================================================== + //============================================================================== struct Internal; std::unique_ptr internal; }; diff --git a/modules/juce_blocks_basics/topology/juce_TopologySource.h b/modules/juce_blocks_basics/topology/juce_TopologySource.h index 899288bf..d7360ba5 100644 --- a/modules/juce_blocks_basics/topology/juce_TopologySource.h +++ b/modules/juce_blocks_basics/topology/juce_TopologySource.h @@ -30,7 +30,7 @@ namespace juce class TopologySource { public: - //========================================================================== + //============================================================================== /** Destructor. */ virtual ~TopologySource() = default; @@ -43,7 +43,7 @@ public: /** Returns true, if the TopologySource is currently trying to connect the block devices */ virtual bool isActive() const = 0; - //========================================================================== + //============================================================================== /** Used to receive callbacks for topology changes */ struct Listener { @@ -71,7 +71,7 @@ public: virtual void cancelAllActiveTouches() noexcept {} protected: - //========================================================================== + //============================================================================== ListenerList listeners; }; diff --git a/modules/juce_box2d/juce_box2d.h b/modules/juce_box2d/juce_box2d.h index 452e6fd9..5080c705 100644 --- a/modules/juce_box2d/juce_box2d.h +++ b/modules/juce_box2d/juce_box2d.h @@ -35,7 +35,7 @@ ID: juce_box2d vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE wrapper for the Box2D physics engine description: The Box2D physics engine and some utility classes. website: http://www.juce.com/juce diff --git a/modules/juce_core/containers/juce_NamedValueSet.h b/modules/juce_core/containers/juce_NamedValueSet.h index c307fc73..9e8f153c 100644 --- a/modules/juce_core/containers/juce_NamedValueSet.h +++ b/modules/juce_core/containers/juce_NamedValueSet.h @@ -89,7 +89,6 @@ public: /** Returns the value of a named item. If the name isn't found, this will return a void variant. - @see getProperty */ const var& operator[] (const Identifier& name) const noexcept; diff --git a/modules/juce_core/containers/juce_OwnedArray.h b/modules/juce_core/containers/juce_OwnedArray.h index 155f7903..f3e92668 100644 --- a/modules/juce_core/containers/juce_OwnedArray.h +++ b/modules/juce_core/containers/juce_OwnedArray.h @@ -281,15 +281,15 @@ public: //============================================================================== /** Appends a new object to the end of the array. - Note that the this object will be deleted by the OwnedArray when it - is removed, so be careful not to delete it somewhere else. + Note that this object will be deleted by the OwnedArray when it is removed, + so be careful not to delete it somewhere else. Also be careful not to add the same object to the array more than once, as this will obviously cause deletion of dangling pointers. @param newObject the new object to add to the array @returns the new object that was added - @see set, insert, addIfNotAlreadyThere, addSorted + @see set, insert, addSorted */ ObjectClass* add (ObjectClass* newObject) { @@ -300,15 +300,15 @@ public: /** Appends a new object to the end of the array. - Note that the this object will be deleted by the OwnedArray when it - is removed, so be careful not to delete it somewhere else. + Note that this object will be deleted by the OwnedArray when it is removed, + so be careful not to delete it somewhere else. Also be careful not to add the same object to the array more than once, as this will obviously cause deletion of dangling pointers. @param newObject the new object to add to the array @returns the new object that was added - @see set, insert, addIfNotAlreadyThere, addSorted + @see set, insert, addSorted */ ObjectClass* add (std::unique_ptr newObject) { @@ -317,8 +317,8 @@ public: /** Inserts a new object into the array at the given index. - Note that the this object will be deleted by the OwnedArray when it - is removed, so be careful not to delete it somewhere else. + Note that this object will be deleted by the OwnedArray when it is removed, + so be careful not to delete it somewhere else. If the index is less than 0 or greater than the size of the array, the element will be added to the end of the array. @@ -331,7 +331,7 @@ public: @param indexToInsertAt the index at which the new element should be inserted @param newObject the new object to add to the array @returns the new object that was added - @see add, addSorted, addIfNotAlreadyThere, set + @see add, addSorted, set */ ObjectClass* insert (int indexToInsertAt, ObjectClass* newObject) { @@ -342,8 +342,8 @@ public: /** Inserts a new object into the array at the given index. - Note that the this object will be deleted by the OwnedArray when it - is removed, so be careful not to delete it somewhere else. + Note that this object will be deleted by the OwnedArray when it is removed, + so be careful not to delete it somewhere else. If the index is less than 0 or greater than the size of the array, the element will be added to the end of the array. @@ -356,7 +356,7 @@ public: @param indexToInsertAt the index at which the new element should be inserted @param newObject the new object to add to the array @returns the new object that was added - @see add, addSorted, addIfNotAlreadyThere, set + @see add, addSorted, set */ ObjectClass* insert (int indexToInsertAt, std::unique_ptr newObject) { diff --git a/modules/juce_core/files/juce_File.cpp b/modules/juce_core/files/juce_File.cpp index 70f87f59..e07968b1 100644 --- a/modules/juce_core/files/juce_File.cpp +++ b/modules/juce_core/files/juce_File.cpp @@ -1197,6 +1197,28 @@ public: expect (demoFolder.deleteRecursively()); expect (! demoFolder.exists()); + + { + URL url ("https://audio.dev/foo/bar/"); + expectEquals (url.toString (false), String ("https://audio.dev/foo/bar/")); + expectEquals (url.getChildURL ("x").toString (false), String ("https://audio.dev/foo/bar/x")); + expectEquals (url.getParentURL().toString (false), String ("https://audio.dev/foo")); + expectEquals (url.getParentURL().getParentURL().toString (false), String ("https://audio.dev/")); + expectEquals (url.getParentURL().getParentURL().getParentURL().toString (false), String ("https://audio.dev/")); + expectEquals (url.getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/foo/x")); + expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/x")); + } + + { + URL url ("https://audio.dev/foo/bar"); + expectEquals (url.toString (false), String ("https://audio.dev/foo/bar")); + expectEquals (url.getChildURL ("x").toString (false), String ("https://audio.dev/foo/bar/x")); + expectEquals (url.getParentURL().toString (false), String ("https://audio.dev/foo")); + expectEquals (url.getParentURL().getParentURL().toString (false), String ("https://audio.dev/")); + expectEquals (url.getParentURL().getParentURL().getParentURL().toString (false), String ("https://audio.dev/")); + expectEquals (url.getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/foo/x")); + expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL ("x").toString (false), String ("https://audio.dev/x")); + } } }; diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp index 890cd368..a7d26cd6 100755 --- a/modules/juce_core/juce_core.cpp +++ b/modules/juce_core/juce_core.cpp @@ -111,7 +111,7 @@ #endif #if JUCE_BELA - #include + #include #endif #undef check diff --git a/modules/juce_core/juce_core.h b/modules/juce_core/juce_core.h index f6c80dc1..9cd41469 100644 --- a/modules/juce_core/juce_core.h +++ b/modules/juce_core/juce_core.h @@ -32,7 +32,7 @@ ID: juce_core vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE core classes 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. website: http://www.juce.com/juce diff --git a/modules/juce_core/memory/juce_OptionalScopedPointer.h b/modules/juce_core/memory/juce_OptionalScopedPointer.h index ad8081db..1c21885e 100644 --- a/modules/juce_core/memory/juce_OptionalScopedPointer.h +++ b/modules/juce_core/memory/juce_OptionalScopedPointer.h @@ -122,6 +122,8 @@ public: { if (! shouldDelete) object.release(); + else + object.reset(); } /** Does the same thing as reset(). */ diff --git a/modules/juce_core/misc/juce_WindowsRegistry.h b/modules/juce_core/misc/juce_WindowsRegistry.h index e1d07613..be61c200 100644 --- a/modules/juce_core/misc/juce_WindowsRegistry.h +++ b/modules/juce_core/misc/juce_WindowsRegistry.h @@ -90,7 +90,7 @@ public: static bool JUCE_CALLTYPE valueExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); /** Returns true if the given key exists in the registry. */ - static bool JUCE_CALLTYPE keyExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); + static bool JUCE_CALLTYPE keyExists (const String& regKeyPath, WoW64Mode mode = WoW64_Default); /** Deletes a registry value. */ static bool JUCE_CALLTYPE deleteValue (const String& regValuePath, WoW64Mode mode = WoW64_Default); diff --git a/modules/juce_core/native/juce_BasicNativeHeaders.h b/modules/juce_core/native/juce_BasicNativeHeaders.h index dc5d53c0..f9281e1f 100644 --- a/modules/juce_core/native/juce_BasicNativeHeaders.h +++ b/modules/juce_core/native/juce_BasicNativeHeaders.h @@ -104,6 +104,7 @@ #include #include #include + #include //============================================================================== #elif JUCE_WINDOWS @@ -241,6 +242,7 @@ #include #include #include + #include //============================================================================== #elif JUCE_BSD @@ -269,6 +271,7 @@ #include #include #include + #include //============================================================================== #elif JUCE_ANDROID @@ -290,6 +293,7 @@ #include #include #include + #include // If you are getting include errors here, then you to re-build the Projucer // and re-save your .jucer file. diff --git a/modules/juce_core/native/juce_android_JNIHelpers.cpp b/modules/juce_core/native/juce_android_JNIHelpers.cpp index 89d70ca7..d9eb2633 100644 --- a/modules/juce_core/native/juce_android_JNIHelpers.cpp +++ b/modules/juce_core/native/juce_android_JNIHelpers.cpp @@ -418,13 +418,27 @@ jobject ActivityLifecycleCallbacks::invoke (jobject proxy, jobject method, jobje auto activity = env->GetArrayLength (args) > 0 ? env->GetObjectArrayElement (args, 0) : (jobject) nullptr; auto bundle = env->GetArrayLength (args) > 1 ? env->GetObjectArrayElement (args, 1) : (jobject) nullptr; - if (methodName == "onActivityCreated") { onActivityCreated (activity, bundle); return nullptr; } - else if (methodName == "onActivityDestroyed") { onActivityDestroyed (activity); return nullptr; } - else if (methodName == "onActivityPaused") { onActivityPaused (activity); return nullptr; } - else if (methodName == "onActivityResumed") { onActivityResumed (activity); return nullptr; } - else if (methodName == "onActivitySaveInstanceState") { onActivitySaveInstanceState (activity, bundle); return nullptr; } - else if (methodName == "onActivityStarted") { onActivityStarted (activity); return nullptr; } - else if (methodName == "onActivityStopped") { onActivityStopped (activity); return nullptr; } + if (methodName == "onActivityPreCreated") { onActivityPreCreated (activity, bundle); return nullptr; } + else if (methodName == "onActivityPreDestroyed") { onActivityPreDestroyed (activity); return nullptr; } + else if (methodName == "onActivityPrePaused") { onActivityPrePaused (activity); return nullptr; } + else if (methodName == "onActivityPreResumed") { onActivityPreResumed (activity); return nullptr; } + else if (methodName == "onActivityPreSaveInstanceState") { onActivityPreSaveInstanceState (activity, bundle); return nullptr; } + else if (methodName == "onActivityPreStarted") { onActivityPreStarted (activity); return nullptr; } + else if (methodName == "onActivityPreStopped") { onActivityPreStopped (activity); return nullptr; } + else if (methodName == "onActivityCreated") { onActivityCreated (activity, bundle); return nullptr; } + else if (methodName == "onActivityDestroyed") { onActivityDestroyed (activity); return nullptr; } + else if (methodName == "onActivityPaused") { onActivityPaused (activity); return nullptr; } + else if (methodName == "onActivityResumed") { onActivityResumed (activity); return nullptr; } + else if (methodName == "onActivitySaveInstanceState") { onActivitySaveInstanceState (activity, bundle); return nullptr; } + else if (methodName == "onActivityStarted") { onActivityStarted (activity); return nullptr; } + else if (methodName == "onActivityStopped") { onActivityStopped (activity); return nullptr; } + else if (methodName == "onActivityPostCreated") { onActivityPostCreated (activity, bundle); return nullptr; } + else if (methodName == "onActivityPostDestroyed") { onActivityPostDestroyed (activity); return nullptr; } + else if (methodName == "onActivityPostPaused") { onActivityPostPaused (activity); return nullptr; } + else if (methodName == "onActivityPostResumed") { onActivityPostResumed (activity); return nullptr; } + else if (methodName == "onActivityPostSaveInstanceState") { onActivityPostSaveInstanceState (activity, bundle); return nullptr; } + else if (methodName == "onActivityPostStarted") { onActivityPostStarted (activity); return nullptr; } + else if (methodName == "onActivityPostStopped") { onActivityPostStopped (activity); return nullptr; } return AndroidInterfaceImplementer::invoke (proxy, method, args); } diff --git a/modules/juce_core/native/juce_android_JNIHelpers.h b/modules/juce_core/native/juce_android_JNIHelpers.h index 753c166f..edf7fadd 100644 --- a/modules/juce_core/native/juce_android_JNIHelpers.h +++ b/modules/juce_core/native/juce_android_JNIHelpers.h @@ -875,13 +875,29 @@ LocalRef CreateJavaInterface (AndroidInterfaceImplementer* implementer, class ActivityLifecycleCallbacks : public AndroidInterfaceImplementer { public: - virtual void onActivityCreated (jobject /*activity*/, jobject /*bundle*/) {} - virtual void onActivityDestroyed (jobject /*activity*/) {} - virtual void onActivityPaused (jobject /*activity*/) {} - virtual void onActivityResumed (jobject /*activity*/) {} - virtual void onActivitySaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {} - virtual void onActivityStarted (jobject /*activity*/) {} - virtual void onActivityStopped (jobject /*activity*/) {} + virtual void onActivityPreCreated (jobject /*activity*/, jobject /*bundle*/) {} + virtual void onActivityPreDestroyed (jobject /*activity*/) {} + virtual void onActivityPrePaused (jobject /*activity*/) {} + virtual void onActivityPreResumed (jobject /*activity*/) {} + virtual void onActivityPreSaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {} + virtual void onActivityPreStarted (jobject /*activity*/) {} + virtual void onActivityPreStopped (jobject /*activity*/) {} + + virtual void onActivityCreated (jobject /*activity*/, jobject /*bundle*/) {} + virtual void onActivityDestroyed (jobject /*activity*/) {} + virtual void onActivityPaused (jobject /*activity*/) {} + virtual void onActivityResumed (jobject /*activity*/) {} + virtual void onActivitySaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {} + virtual void onActivityStarted (jobject /*activity*/) {} + virtual void onActivityStopped (jobject /*activity*/) {} + + virtual void onActivityPostCreated (jobject /*activity*/, jobject /*bundle*/) {} + virtual void onActivityPostDestroyed (jobject /*activity*/) {} + virtual void onActivityPostPaused (jobject /*activity*/) {} + virtual void onActivityPostResumed (jobject /*activity*/) {} + virtual void onActivityPostSaveInstanceState (jobject /*activity*/, jobject /*bundle*/) {} + virtual void onActivityPostStarted (jobject /*activity*/) {} + virtual void onActivityPostStopped (jobject /*activity*/) {} private: jobject invoke (jobject, jobject, jobjectArray) override; diff --git a/modules/juce_core/native/juce_linux_Network.cpp b/modules/juce_core/native/juce_linux_Network.cpp index 5ec41865..61e6f3a3 100644 --- a/modules/juce_core/native/juce_linux_Network.cpp +++ b/modules/juce_core/native/juce_linux_Network.cpp @@ -205,16 +205,10 @@ public: bytesToRead = static_cast (chunkEnd - position); } - fd_set readbits; - FD_ZERO (&readbits); - FD_SET (socketHandle, &readbits); + pollfd pfd { socketHandle, POLLIN, 0 }; - struct timeval tv; - tv.tv_sec = jmax (1, timeOutMs / 1000); - tv.tv_usec = 0; - - if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0) - return 0; // (timeout) + if (poll (&pfd, 1, timeOutMs) <= 0) + return 0; // (timeout) auto bytesRead = jmax (0, (int) recv (socketHandle, buffer, (size_t) bytesToRead, MSG_WAITALL)); diff --git a/modules/juce_core/native/juce_posix_NamedPipe.cpp b/modules/juce_core/native/juce_posix_NamedPipe.cpp index af8b3964..72b810a5 100644 --- a/modules/juce_core/native/juce_posix_NamedPipe.cpp +++ b/modules/juce_core/native/juce_posix_NamedPipe.cpp @@ -172,15 +172,8 @@ private: static void waitForInput (int handle, int timeoutMsecs) noexcept { - struct timeval timeout; - timeout.tv_sec = timeoutMsecs / 1000; - timeout.tv_usec = (timeoutMsecs % 1000) * 1000; - - fd_set rset; - FD_ZERO (&rset); - FD_SET (handle, &rset); - - select (handle + 1, &rset, nullptr, nullptr, &timeout); + pollfd pfd { handle, POLLIN, 0 }; + poll (&pfd, 1, timeoutMsecs); } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h index f2dcadad..e035a107 100644 --- a/modules/juce_core/native/juce_posix_SharedCode.h +++ b/modules/juce_core/native/juce_posix_SharedCode.h @@ -400,13 +400,19 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int if (juce_stat (fullPath, info)) { + #if JUCE_MAC || (JUCE_IOS && __DARWIN_ONLY_64_BIT_INO_T) + modificationTime = (int64) info.st_mtimespec.tv_sec * 1000 + info.st_mtimespec.tv_nsec / 1000000; + accessTime = (int64) info.st_atimespec.tv_sec * 1000 + info.st_atimespec.tv_nsec / 1000000; + creationTime = (int64) info.st_birthtimespec.tv_sec * 1000 + info.st_birthtimespec.tv_nsec / 1000000; + #else modificationTime = (int64) info.st_mtime * 1000; accessTime = (int64) info.st_atime * 1000; - #if JUCE_MAC || JUCE_IOS + #if JUCE_IOS creationTime = (int64) info.st_birthtime * 1000; #else creationTime = (int64) info.st_ctime * 1000; #endif + #endif } } @@ -416,11 +422,32 @@ bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 if ((modificationTime != 0 || accessTime != 0) && juce_stat (fullPath, info)) { + #if JUCE_MAC || (JUCE_IOS && __DARWIN_ONLY_64_BIT_INO_T) + struct timeval times[2]; + + bool setModificationTime = (modificationTime != 0); + bool setAccessTime = (accessTime != 0); + + times[0].tv_sec = setAccessTime ? static_cast<__darwin_time_t> (accessTime / 1000) + : info.st_atimespec.tv_sec; + + times[0].tv_usec = setAccessTime ? static_cast<__darwin_suseconds_t> ((accessTime % 1000) * 1000) + : static_cast<__darwin_suseconds_t> (info.st_atimespec.tv_nsec / 1000); + + times[1].tv_sec = setModificationTime ? static_cast<__darwin_time_t> (modificationTime / 1000) + : info.st_mtimespec.tv_sec; + + times[1].tv_usec = setModificationTime ? static_cast<__darwin_suseconds_t> ((modificationTime % 1000) * 1000) + : static_cast<__darwin_suseconds_t> (info.st_mtimespec.tv_nsec / 1000); + + return utimes (fullPath.toUTF8(), times) == 0; + #else struct utimbuf times; times.actime = accessTime != 0 ? static_cast (accessTime / 1000) : static_cast (info.st_atime); times.modtime = modificationTime != 0 ? static_cast (modificationTime / 1000) : static_cast (info.st_mtime); return utime (fullPath.toUTF8(), ×) == 0; + #endif } return false; diff --git a/modules/juce_core/native/juce_win32_Registry.cpp b/modules/juce_core/native/juce_win32_Registry.cpp index e1b5f5b8..afd29824 100644 --- a/modules/juce_core/native/juce_win32_Registry.cpp +++ b/modules/juce_core/native/juce_win32_Registry.cpp @@ -49,7 +49,7 @@ struct RegistryKeyWrapper ~RegistryKeyWrapper() { - if (key != 0) + if (key != nullptr) RegCloseKey (key); } @@ -73,7 +73,7 @@ struct RegistryKeyWrapper { const RegistryKeyWrapper key (regValuePath, true, wow64Flags); - return key.key != 0 + return key.key != nullptr && RegSetValueEx (key.key, key.wideCharValueName, 0, type, reinterpret_cast (data), (DWORD) dataSize) == ERROR_SUCCESS; @@ -83,7 +83,7 @@ struct RegistryKeyWrapper { const RegistryKeyWrapper key (regValuePath, false, wow64Flags); - if (key.key != 0) + if (key.key != nullptr) { for (unsigned long bufferSize = 1024; ; bufferSize *= 2) { @@ -121,16 +121,16 @@ struct RegistryKeyWrapper return defaultValue; } - static bool keyExists (const String& regValuePath, const DWORD wow64Flags) + static bool keyExists (const String& regKeyPath, const DWORD wow64Flags) { - return RegistryKeyWrapper (regValuePath, false, wow64Flags).key != 0; + return RegistryKeyWrapper (regKeyPath + "\\", false, wow64Flags).key != nullptr; } static bool valueExists (const String& regValuePath, const DWORD wow64Flags) { const RegistryKeyWrapper key (regValuePath, false, wow64Flags); - if (key.key == 0) + if (key.key == nullptr) return false; unsigned char buffer [512]; @@ -143,7 +143,7 @@ struct RegistryKeyWrapper return result == ERROR_SUCCESS || result == ERROR_MORE_DATA; } - HKEY key = 0; + HKEY key = nullptr; const wchar_t* wideCharValueName = nullptr; String valueName; @@ -186,23 +186,23 @@ bool JUCE_CALLTYPE WindowsRegistry::valueExists (const String& regValuePath, WoW return RegistryKeyWrapper::valueExists (regValuePath, (DWORD) mode); } -bool JUCE_CALLTYPE WindowsRegistry::keyExists (const String& regValuePath, WoW64Mode mode) +bool JUCE_CALLTYPE WindowsRegistry::keyExists (const String& regKeyPath, WoW64Mode mode) { - return RegistryKeyWrapper::keyExists (regValuePath, (DWORD) mode); + return RegistryKeyWrapper::keyExists (regKeyPath, (DWORD) mode); } bool JUCE_CALLTYPE WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode) { const RegistryKeyWrapper key (regValuePath, true, (DWORD) mode); - return key.key != 0 && RegDeleteValue (key.key, key.wideCharValueName) == ERROR_SUCCESS; + return key.key != nullptr && RegDeleteValue (key.key, key.wideCharValueName) == ERROR_SUCCESS; } static bool deleteKeyNonRecursive (const String& regKeyPath, WindowsRegistry::WoW64Mode mode) { const RegistryKeyWrapper key (regKeyPath, true, (DWORD) mode); - return key.key != 0 && RegDeleteKey (key.key, key.wideCharValueName) == ERROR_SUCCESS; + return key.key != nullptr && RegDeleteKey (key.key, key.wideCharValueName) == ERROR_SUCCESS; } bool JUCE_CALLTYPE WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode) diff --git a/modules/juce_core/network/juce_Socket.cpp b/modules/juce_core/network/juce_Socket.cpp index 8430badf..1c15fc56 100644 --- a/modules/juce_core/network/juce_Socket.cpp +++ b/modules/juce_core/network/juce_Socket.cpp @@ -33,19 +33,22 @@ namespace juce #endif #if JUCE_WINDOWS - typedef int juce_socklen_t; - typedef int juce_recvsend_size_t; - typedef SOCKET SocketHandle; + using juce_socklen_t = int; + using juce_recvsend_size_t = int; + using SocketHandle = SOCKET; + #if ! JUCE_MINGW + using pollfd = WSAPOLLFD; + #endif static const SocketHandle invalidSocket = INVALID_SOCKET; #elif JUCE_ANDROID - typedef socklen_t juce_socklen_t; - typedef size_t juce_recvsend_size_t; - typedef int SocketHandle; + using juce_socklen_t = socklen_t; + using juce_recvsend_size_t = size_t; + using SocketHandle = int; static const SocketHandle invalidSocket = -1; #else - typedef socklen_t juce_socklen_t; - typedef socklen_t juce_recvsend_size_t; - typedef int SocketHandle; + using juce_socklen_t = socklen_t; + using juce_recvsend_size_t = socklen_t; + using SocketHandle = int; static const SocketHandle invalidSocket = -1; #endif @@ -87,7 +90,7 @@ namespace SocketHelpers static bool resetSocketOptions (SocketHandle handle, bool isDatagram, bool allowBroadcast) noexcept { - return handle >= 0 + return handle != invalidSocket && setOption (handle, SO_RCVBUF, (int) 65536) && setOption (handle, SO_SNDBUF, (int) 65536) && (isDatagram ? ((! allowBroadcast) || setOption (handle, SO_BROADCAST, (int) 1)) @@ -147,7 +150,7 @@ namespace SocketHelpers static bool bindSocket (SocketHandle handle, int port, const String& address) noexcept { - if (handle < 0 || ! isValidPortNumber (port)) + if (handle == invalidSocket || ! isValidPortNumber (port)) return false; struct sockaddr_in addr; @@ -163,7 +166,7 @@ namespace SocketHelpers static int getBoundPort (SocketHandle handle) noexcept { - if (handle >= 0) + if (handle != invalidSocket) { struct sockaddr_in addr; socklen_t len = sizeof (addr); @@ -186,6 +189,33 @@ namespace SocketHelpers return "0.0.0.0"; } + static bool setSocketBlockingState (SocketHandle handle, bool shouldBlock) noexcept + { + #if JUCE_WINDOWS + u_long nonBlocking = shouldBlock ? 0 : (u_long) 1; + return ioctlsocket (handle, FIONBIO, &nonBlocking) == 0; + #else + int socketFlags = fcntl (handle, F_GETFL, 0); + + if (socketFlags == -1) + return false; + + if (shouldBlock) + socketFlags &= ~O_NONBLOCK; + else + socketFlags |= O_NONBLOCK; + + return fcntl (handle, F_SETFL, socketFlags) == 0; + #endif + } + + #if ! JUCE_WINDOWS + static bool getSocketBlockingState (SocketHandle handle) + { + return (fcntl (handle, F_GETFL, 0) & O_NONBLOCK) == 0; + } + #endif + static int readSocket (SocketHandle handle, void* destBuffer, int maxBytesToRead, std::atomic& connected, @@ -194,6 +224,11 @@ namespace SocketHelpers String* senderIP = nullptr, int* senderPort = nullptr) noexcept { + #if ! JUCE_WINDOWS + if (blockUntilSpecifiedAmountHasArrived != getSocketBlockingState (handle)) + #endif + setSocketBlockingState (handle, blockUntilSpecifiedAmountHasArrived); + int bytesRead = 0; while (bytesRead < maxBytesToRead) @@ -251,8 +286,9 @@ namespace SocketHelpers if (! lock.isLocked()) return -1; - int h = handle.load(); + auto h = handle.load(); + #if JUCE_MINGW struct timeval timeout; struct timeval* timeoutp; @@ -276,24 +312,36 @@ namespace SocketHelpers fd_set* const prset = forReading ? &rset : nullptr; fd_set* const pwset = forReading ? nullptr : &wset; - #if JUCE_WINDOWS if (select ((int) h + 1, prset, pwset, 0, timeoutp) < 0) return -1; #else - { - int result = 0; + short eventsFlag = (forReading ? POLLIN : POLLOUT); + pollfd pfd { (SocketHandle) h, eventsFlag, 0 }; - for (;;) - { - result = select (h + 1, prset, pwset, nullptr, timeoutp); + int result = 0; - if (result >= 0 || errno != EINTR) - break; + for (;;) + { + #if JUCE_WINDOWS + result = WSAPoll (&pfd, 1, timeoutMsecs); + #else + result = poll (&pfd, 1, timeoutMsecs); + #endif + + if (result >= 0 + #if JUCE_WINDOWS + || result == SOCKET_ERROR + #else + || errno != EINTR + #endif + ) + { + break; } - - if (result < 0) - return -1; } + + if (result < 0) + return -1; #endif // we are closing @@ -309,26 +357,10 @@ namespace SocketHelpers return -1; } + #if JUCE_MINGW return FD_ISSET (h, forReading ? &rset : &wset) ? 1 : 0; - } - - static bool setSocketBlockingState (SocketHandle handle, bool shouldBlock) noexcept - { - #if JUCE_WINDOWS - u_long nonBlocking = shouldBlock ? 0 : (u_long) 1; - return ioctlsocket (handle, FIONBIO, &nonBlocking) == 0; #else - int socketFlags = fcntl (handle, F_GETFL, 0); - - if (socketFlags == -1) - return false; - - if (shouldBlock) - socketFlags &= ~O_NONBLOCK; - else - socketFlags |= O_NONBLOCK; - - return fcntl (handle, F_SETFL, socketFlags) == 0; + return (pfd.revents & eventsFlag) != 0; #endif } @@ -688,8 +720,6 @@ int DatagramSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock return -1; std::atomic connected { true }; - - SocketHelpers::setSocketBlockingState (handle, shouldBlock); return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, connected, shouldBlock, readLock); } @@ -700,8 +730,6 @@ int DatagramSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock return -1; std::atomic connected { true }; - - SocketHelpers::setSocketBlockingState (handle, shouldBlock); return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, connected, shouldBlock, readLock, &senderIPAddress, &senderPort); } diff --git a/modules/juce_core/network/juce_URL.cpp b/modules/juce_core/network/juce_URL.cpp index 72d2536e..26169129 100644 --- a/modules/juce_core/network/juce_URL.cpp +++ b/modules/juce_core/network/juce_URL.cpp @@ -135,7 +135,7 @@ URL::DownloadTask::DownloadTask() {} URL::DownloadTask::~DownloadTask() {} //============================================================================== -URL::URL() noexcept {} +URL::URL() {} URL::URL (const String& u) : url (u) { @@ -171,7 +171,6 @@ URL::URL (File localFile) url = "/" + url; } - url = "file://" + url; jassert (isWellFormed()); @@ -287,6 +286,20 @@ namespace URLHelpers else path += suffix; } + + static String removeLastPathSection (const String& url) + { + auto startOfPath = findStartOfPath (url); + auto lastSlash = url.lastIndexOfChar ('/'); + + if (lastSlash > startOfPath && lastSlash == url.length() - 1) + return removeLastPathSection (url.dropLastCharacters (1)); + + if (lastSlash < 0) + return url; + + return url.substring (0, std::max (startOfPath, lastSlash)); + } } void URL::addParameter (const String& name, const String& value) @@ -344,10 +357,10 @@ String URL::getScheme() const return url.substring (0, URLHelpers::findEndOfScheme (url) - 1); } -#ifndef JUCE_ANDROID +#if ! JUCE_ANDROID bool URL::isLocalFile() const { - return (getScheme() == "file"); + return getScheme() == "file"; } File URL::getLocalFile() const @@ -371,7 +384,7 @@ File URL::fileFromFileSchemeURL (const URL& fileURL) auto path = removeEscapeChars (fileURL.getDomainInternal (true)).replace ("+", "%2B"); - #ifdef JUCE_WINDOWS + #if JUCE_WINDOWS bool isUncPath = (! fileURL.url.startsWith ("file:///")); #else path = File::getSeparatorString() + path; @@ -382,7 +395,7 @@ File URL::fileFromFileSchemeURL (const URL& fileURL) for (auto urlElement : urlElements) path += File::getSeparatorString() + removeEscapeChars (urlElement.replace ("+", "%2B")); - #ifdef JUCE_WINDOWS + #if JUCE_WINDOWS if (isUncPath) path = "\\\\" + path; #endif @@ -406,10 +419,10 @@ URL URL::withNewDomainAndPath (const String& newURL) const URL URL::withNewSubPath (const String& newPath) const { - const int startOfPath = URLHelpers::findStartOfPath (url); - URL u (*this); + auto startOfPath = URLHelpers::findStartOfPath (url); + if (startOfPath > 0) u.url = url.substring (0, startOfPath); @@ -417,6 +430,13 @@ URL URL::withNewSubPath (const String& newPath) const return u; } +URL URL::getParentURL() const +{ + URL u (*this); + u.url = URLHelpers::removeLastPathSection (u.url); + return u; +} + URL URL::getChildURL (const String& subPath) const { URL u (*this); @@ -482,18 +502,15 @@ void URL::createHeadersAndPostData (String& headers, MemoryBlock& postDataToWrit //============================================================================== bool URL::isProbablyAWebsiteURL (const String& possibleURL) { - static const char* validProtocols[] = { "http:", "ftp:", "https:" }; - - for (auto* protocol : validProtocols) + for (auto* protocol : { "http:", "https:", "ftp:" }) if (possibleURL.startsWithIgnoreCase (protocol)) return true; - if (possibleURL.containsChar ('@') - || possibleURL.containsChar (' ')) + if (possibleURL.containsChar ('@') || possibleURL.containsChar (' ')) return false; - const String topLevelDomain (possibleURL.upToFirstOccurrenceOf ("/", false, false) - .fromLastOccurrenceOf (".", false, false)); + auto topLevelDomain = possibleURL.upToFirstOccurrenceOf ("/", false, false) + .fromLastOccurrenceOf (".", false, false); return topLevelDomain.isNotEmpty() && topLevelDomain.length() <= 3; } @@ -520,8 +537,7 @@ String URL::getDomainInternal (bool ignorePort) const } #if JUCE_IOS -URL::Bookmark::Bookmark (void* bookmarkToUse) - : data (bookmarkToUse) +URL::Bookmark::Bookmark (void* bookmarkToUse) : data (bookmarkToUse) { } @@ -612,12 +628,10 @@ private: return urlToUse.getLocalFile(); } - else - { - auto desc = [error localizedDescription]; - ignoreUnused (desc); - jassertfalse; - } + + auto desc = [error localizedDescription]; + ignoreUnused (desc); + jassertfalse; } return urlToUse.getLocalFile(); @@ -659,10 +673,9 @@ InputStream* URL::createInputStream (bool usePostCommand, #else return getLocalFile().createInputStream(); #endif - } - std::unique_ptr wi (new WebInputStream (*this, usePostCommand)); + auto wi = std::make_unique (*this, usePostCommand); struct ProgressCallbackCaller : public WebInputStream::Listener { diff --git a/modules/juce_core/network/juce_URL.h b/modules/juce_core/network/juce_URL.h index 86603395..6e608822 100644 --- a/modules/juce_core/network/juce_URL.h +++ b/modules/juce_core/network/juce_URL.h @@ -39,7 +39,7 @@ class JUCE_API URL public: //============================================================================== /** Creates an empty URL. */ - URL() noexcept; + URL(); /** Creates a URL from a string. This will parse any embedded parameters after a '?' character and store them @@ -148,6 +148,11 @@ public: */ URL withNewSubPath (const String& newPath) const; + /** Attempts to return a URL which is the parent folder containing this URL. + If there isn't a parent, this method will just return a copy of this URL. + */ + URL getParentURL() const; + /** Returns a new URL that refers to a sub-path relative to this one. E.g. if the URL is "http://www.xyz.com/foo" and you call this with "bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for @@ -263,7 +268,7 @@ public: URL withPOSTData (const MemoryBlock& postData) const; /** Returns the data that was set using withPOSTData(). */ - String getPostData() const noexcept { return postData.toString(); } + String getPostData() const { return postData.toString(); } /** Returns the data that was set using withPOSTData() as MemoryBlock. */ const MemoryBlock& getPostDataAsMemoryBlock() const noexcept { return postData; } @@ -338,12 +343,12 @@ public: InputStream* createInputStream (bool doPostLikeRequest, OpenStreamProgressCallback* progressCallback = nullptr, void* progressCallbackContext = nullptr, - String extraHeaders = String(), + String extraHeaders = {}, int connectionTimeOutMs = 0, StringPairArray* responseHeaders = nullptr, int* statusCode = nullptr, int numRedirectsToFollow = 5, - String httpRequestCmd = String()) const; + String httpRequestCmd = {}) const; /** Attempts to open an output stream to a URL for writing diff --git a/modules/juce_core/system/juce_CompilerSupport.h b/modules/juce_core/system/juce_CompilerSupport.h index e9861cfb..42712c73 100644 --- a/modules/juce_core/system/juce_CompilerSupport.h +++ b/modules/juce_core/system/juce_CompilerSupport.h @@ -117,7 +117,7 @@ namespace std template unique_ptr make_unique (Args&&... args) { - return unique_ptr (new T (forward (args)...)); + return unique_ptr (new T (std::forward (args)...)); } } #endif diff --git a/modules/juce_core/system/juce_StandardHeader.h b/modules/juce_core/system/juce_StandardHeader.h index 316de1fb..34aed373 100644 --- a/modules/juce_core/system/juce_StandardHeader.h +++ b/modules/juce_core/system/juce_StandardHeader.h @@ -29,7 +29,7 @@ */ #define JUCE_MAJOR_VERSION 5 #define JUCE_MINOR_VERSION 4 -#define JUCE_BUILDNUMBER 4 +#define JUCE_BUILDNUMBER 5 /** Current JUCE version number. diff --git a/modules/juce_core/time/juce_PerformanceCounter.cpp b/modules/juce_core/time/juce_PerformanceCounter.cpp index 4650e16f..5e15212d 100644 --- a/modules/juce_core/time/juce_PerformanceCounter.cpp +++ b/modules/juce_core/time/juce_PerformanceCounter.cpp @@ -43,7 +43,8 @@ PerformanceCounter::PerformanceCounter (const String& name, int runsPerPrintout, PerformanceCounter::~PerformanceCounter() { - printStatistics(); + if (stats.numRuns > 0) + printStatistics(); } PerformanceCounter::Statistics::Statistics() noexcept diff --git a/modules/juce_cryptography/juce_cryptography.h b/modules/juce_cryptography/juce_cryptography.h index da119741..86d5ca36 100644 --- a/modules/juce_cryptography/juce_cryptography.h +++ b/modules/juce_cryptography/juce_cryptography.h @@ -35,7 +35,7 @@ ID: juce_cryptography vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE cryptography classes description: Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc. website: http://www.juce.com/juce diff --git a/modules/juce_data_structures/juce_data_structures.h b/modules/juce_data_structures/juce_data_structures.h index 0bca62ba..85ec23f5 100644 --- a/modules/juce_data_structures/juce_data_structures.h +++ b/modules/juce_data_structures/juce_data_structures.h @@ -35,7 +35,7 @@ ID: juce_data_structures vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE data model helper classes description: Classes for undo/redo management, and smart data structures. website: http://www.juce.com/juce diff --git a/modules/juce_dsp/containers/juce_AudioBlock.h b/modules/juce_dsp/containers/juce_AudioBlock.h index 6ffcda75..7f289cdf 100644 --- a/modules/juce_dsp/containers/juce_AudioBlock.h +++ b/modules/juce_dsp/containers/juce_AudioBlock.h @@ -78,15 +78,15 @@ public: //============================================================================== /** Create a zero-sized AudioBlock. */ - forcedinline AudioBlock() noexcept = default; + AudioBlock() noexcept = default; /** Creates an AudioBlock from a pointer to an array of channels. AudioBlock does not copy nor own the memory pointed to by dataToUse. Therefore it is the user's responsibility to ensure that the memory is retained throughout the life-time of the AudioBlock and released when no longer needed. */ - forcedinline AudioBlock (SampleType* const* channelData, - size_t numberOfChannels, size_t numberOfSamples) noexcept + constexpr AudioBlock (SampleType* const* channelData, + size_t numberOfChannels, size_t numberOfSamples) noexcept : channels (channelData), numChannels (static_cast (numberOfChannels)), numSamples (numberOfSamples) @@ -98,8 +98,8 @@ public: Therefore it is the user's responsibility to ensure that the memory is retained throughout the life-time of the AudioBlock and released when no longer needed. */ - forcedinline AudioBlock (SampleType* const* channelData, size_t numberOfChannels, - size_t startSampleIndex, size_t numberOfSamples) noexcept + constexpr AudioBlock (SampleType* const* channelData, size_t numberOfChannels, + size_t startSampleIndex, size_t numberOfSamples) noexcept : channels (channelData), numChannels (static_cast (numberOfChannels)), startSample (startSampleIndex), @@ -144,7 +144,7 @@ public: throughout the life-time of the AudioBlock without being modified. */ template - AudioBlock (AudioBuffer& buffer) noexcept + constexpr AudioBlock (AudioBuffer& buffer) noexcept : channels (buffer.getArrayOfWritePointers()), numChannels (static_cast (buffer.getNumChannels())), numSamples (static_cast (buffer.getNumSamples())) @@ -196,7 +196,7 @@ public: //============================================================================== template - bool operator== (const AudioBlock& other) const noexcept + constexpr bool operator== (const AudioBlock& other) const noexcept { return std::equal (channels, channels + numChannels, @@ -207,25 +207,20 @@ public: } template - bool operator!= (const AudioBlock& other) const noexcept + constexpr bool operator!= (const AudioBlock& other) const noexcept { return ! (*this == other); } //============================================================================== - forcedinline size_t getNumSamples() const noexcept { return numSamples; } - forcedinline size_t getNumChannels() const noexcept { return static_cast (numChannels); } + /** Returns the number of channels referenced by this block. */ + constexpr size_t getNumChannels() const noexcept { return static_cast (numChannels); } - /** Returns a raw pointer into one of the channels in this block. */ - forcedinline const SampleType* getChannelPointer (size_t channel) const noexcept - { - jassert (channel < numChannels); - jassert (numSamples > 0); - return channels[channel] + startSample; - } + /** Returns the number of samples referenced by this block. */ + constexpr size_t getNumSamples() const noexcept { return numSamples; } /** Returns a raw pointer into one of the channels in this block. */ - forcedinline SampleType* getChannelPointer (size_t channel) noexcept + SampleType* getChannelPointer (size_t channel) const noexcept { jassert (channel < numChannels); jassert (numSamples > 0); @@ -233,7 +228,7 @@ public: } /** Returns an AudioBlock that represents one of the channels in this block. */ - forcedinline AudioBlock getSingleChannelBlock (size_t channel) const noexcept + AudioBlock getSingleChannelBlock (size_t channel) const noexcept { jassert (channel < numChannels); return AudioBlock (channels + channel, 1, startSample, numSamples); @@ -243,7 +238,7 @@ public: @param channelStart First channel of the subset @param numChannelsToUse Count of channels in the subset */ - forcedinline AudioBlock getSubsetChannelBlock (size_t channelStart, size_t numChannelsToUse) const noexcept + AudioBlock getSubsetChannelBlock (size_t channelStart, size_t numChannelsToUse) const noexcept { jassert (channelStart < numChannels); jassert ((channelStart + numChannelsToUse) <= numChannels); @@ -260,7 +255,7 @@ public: { jassert (isPositiveAndBelow (channel, numChannels)); jassert (isPositiveAndBelow (sampleIndex, numSamples)); - return channels[channel][startSample + sampleIndex]; + return channels[channel][(size_t) startSample + (size_t) sampleIndex]; } /** Modifies a sample in the buffer. @@ -268,11 +263,11 @@ public: an assertion will be thrown, but in a release build, you're into 'undefined behaviour' territory. */ - void setSample (int destChannel, int destSample, SampleType newValue) noexcept + void setSample (int destChannel, int destSample, SampleType newValue) const noexcept { jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (isPositiveAndBelow (destSample, numSamples)); - channels[destChannel][startSample + destSample] = newValue; + channels[destChannel][(size_t) startSample + (size_t) destSample] = newValue; } /** Adds a value to a sample in the buffer. @@ -280,79 +275,52 @@ public: an assertion will be thrown, but in a release build, you're into 'undefined behaviour' territory. */ - void addSample (int destChannel, int destSample, SampleType valueToAdd) noexcept + void addSample (int destChannel, int destSample, SampleType valueToAdd) const noexcept { jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (isPositiveAndBelow (destSample, numSamples)); - channels[destChannel][startSample + destSample] += valueToAdd; + channels[destChannel][(size_t) startSample + (size_t) destSample] += valueToAdd; } //============================================================================== - /** Clear the memory described by this AudioBlock. */ - forcedinline AudioBlock& clear() noexcept - { - auto n = static_cast (numSamples * sizeFactor); - - for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::clear (channelPtr (ch), n); + /** Clears the memory referenced by this AudioBlock. */ + AudioBlock& clear() noexcept { clearInternal(); return *this; } + const AudioBlock& clear() const noexcept { clearInternal(); return *this; } - return *this; - } - - /** Fill memory with value. */ - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE fill (SampleType value) noexcept - { - auto n = static_cast (numSamples * sizeFactor); - - for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::fill (channelPtr (ch), value, n); - - return *this; - } + /** Fills the memory referenced by this AudioBlock with value. */ + AudioBlock& JUCE_VECTOR_CALLTYPE fill (SampleType value) noexcept { fillInternal (value); return *this; } + const AudioBlock& JUCE_VECTOR_CALLTYPE fill (SampleType value) const noexcept { fillInternal (value); return *this; } - /** Copy the values in src to the receiver. */ + /** Copies the values in src to this block. */ template - forcedinline AudioBlock& copy (const AudioBlock& src) noexcept - { - auto maxChannels = jmin (src.numChannels, numChannels); - auto n = static_cast (jmin (src.numSamples, numSamples) * sizeFactor); - - for (size_t ch = 0; ch < maxChannels; ++ch) - FloatVectorOperations::copy (channelPtr (ch), src.channelPtr (ch), n); - - return *this; - } + AudioBlock& copyFrom (const AudioBlock& src) noexcept { copyFromInternal (src); return *this; } + template + const AudioBlock& copyFrom (const AudioBlock& src) const noexcept { copyFromInternal (src); return *this; } - /** Copy the values from a JUCE's AudioBuffer to the receiver. + /** Copy the values from a JUCE's AudioBuffer to this block. All indices and sizes are in the receiver's units, i.e. if SampleType is a SIMDRegister then incrementing srcPos by one will increase the sample position in the AudioBuffer's units by a factor of SIMDRegister::SIMDNumElements. */ - forcedinline AudioBlock& copyFrom (const AudioBuffer& src, size_t srcPos = 0, size_t dstPos = 0, - size_t numElements = std::numeric_limits::max()) - { - auto srclen = static_cast (src.getNumSamples()) / sizeFactor; - auto n = static_cast (jmin (srclen - srcPos, numSamples - dstPos, numElements) * sizeFactor); - auto maxChannels = jmin (static_cast (src.getNumChannels()), static_cast (numChannels)); - - for (size_t ch = 0; ch < maxChannels; ++ch) - FloatVectorOperations::copy (channelPtr (ch) + dstPos, - src.getReadPointer (static_cast (ch), - static_cast (srcPos * sizeFactor)), - n); + template + AudioBlock& copyFrom (const AudioBuffer& src, + size_t srcPos = 0, size_t dstPos = 0, + size_t numElements = std::numeric_limits::max()) { copyFromInternal (src, srcPos, dstPos, numElements); return *this; } + template + const AudioBlock& copyFrom (const AudioBuffer& src, + size_t srcPos = 0, size_t dstPos = 0, + size_t numElements = std::numeric_limits::max()) const { copyFromInternal (src, srcPos, dstPos, numElements); return *this; } - return *this; - } - /** Copy the values from the receiver to a JUCE's AudioBuffer. + /** Copies the values from this block to an AudioBuffer. All indices and sizes are in the receiver's units, i.e. if SampleType is a SIMDRegister then incrementing dstPos by one will increase the sample position in the AudioBuffer's units by a factor of SIMDRegister::SIMDNumElements. */ - forcedinline const AudioBlock& copyTo (AudioBuffer& dst, size_t srcPos = 0, size_t dstPos = 0, - size_t numElements = std::numeric_limits::max()) const + void copyTo (AudioBuffer::type>& dst, size_t srcPos = 0, size_t dstPos = 0, + size_t numElements = std::numeric_limits::max()) const { auto dstlen = static_cast (dst.getNumSamples()) / sizeFactor; auto n = static_cast (jmin (numSamples - srcPos, dstlen - dstPos, numElements) * sizeFactor); @@ -361,30 +329,19 @@ public: for (size_t ch = 0; ch < maxChannels; ++ch) FloatVectorOperations::copy (dst.getWritePointer (static_cast (ch), static_cast (dstPos * sizeFactor)), - channelPtr (ch) + srcPos, n); - - return *this; + getChannelPointer (ch) + srcPos, n); } - /** Move memory within the receiver from the position srcPos to the position dstPos. + /** Move memory within this block from the position srcPos to the position dstPos. If numElements is not specified then move will move the maximum amount of memory. */ - forcedinline AudioBlock& move (size_t srcPos, size_t dstPos, - size_t numElements = std::numeric_limits::max()) noexcept - { - jassert (srcPos <= numSamples && dstPos <= numSamples); - auto len = jmin (numSamples - srcPos, numSamples - dstPos, numElements) * sizeof (SampleType); - - if (len != 0) - for (size_t ch = 0; ch < numChannels; ++ch) - ::memmove (getChannelPointer (ch) + dstPos, - getChannelPointer (ch) + srcPos, len); - - return *this; - } + AudioBlock& move (size_t srcPos, size_t dstPos, + size_t numElements = std::numeric_limits::max()) noexcept { moveInternal (srcPos, dstPos, numElements); return *this; } + const AudioBlock& move (size_t srcPos, size_t dstPos, + size_t numElements = std::numeric_limits::max()) const noexcept { moveInternal (srcPos, dstPos, numElements); return *this; } //============================================================================== - /** Return a new AudioBlock pointing to a sub-block inside the receiver. This + /** Return a new AudioBlock pointing to a sub-block inside this block. This function does not copy the memory and you must ensure that the original memory pointed to by the receiver remains valid through-out the life-time of the returned sub-block. @@ -393,7 +350,7 @@ public: will become the first element of the return value. @param newLength The number of elements of the newly created sub-block. */ - inline AudioBlock getSubBlock (size_t newOffset, size_t newLength) const noexcept + AudioBlock getSubBlock (size_t newOffset, size_t newLength) const noexcept { jassert (newOffset < numSamples); jassert (newOffset + newLength <= numSamples); @@ -401,168 +358,391 @@ public: return AudioBlock (channels, numChannels, startSample + newOffset, newLength); } - /** Return a new AudioBlock pointing to a sub-block inside the receiver. This + /** Return a new AudioBlock pointing to a sub-block inside this block. This function does not copy the memory and you must ensure that the original memory pointed to by the receiver remains valid through-out the life-time of the returned sub-block. - @param newOffset The index of an element inside the receiver which will + @param newOffset The index of an element inside the block which will will become the first element of the return value. The return value will include all subsequent elements of the receiver. */ - inline AudioBlock getSubBlock (size_t newOffset) const noexcept + AudioBlock getSubBlock (size_t newOffset) const noexcept { return getSubBlock (newOffset, getNumSamples() - newOffset); } //============================================================================== - /** Adds a fixed value to the receiver. */ - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE add (SampleType value) noexcept + /** Adds a fixed value to the elements in this block. */ + AudioBlock& JUCE_VECTOR_CALLTYPE add (SampleType value) noexcept { addInternal (value); return *this; } + const AudioBlock& JUCE_VECTOR_CALLTYPE add (SampleType value) const noexcept { addInternal (value); return *this; } + + /** Adds the elements in the src block to the elements in this block. */ + template + AudioBlock& add (AudioBlock src) noexcept { addInternal (src); return *this; } + template + const AudioBlock& add (AudioBlock src) const noexcept { addInternal (src); return *this; } + + /** Adds a fixed value to each source value and replaces the contents of this block. */ + template + AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock src, SampleType value) noexcept { replaceWithSumOfInternal (src, value); return *this; } + template + const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock src, SampleType value) const noexcept { replaceWithSumOfInternal (src, value); return *this; } + + /** Adds each source1 value to the corresponding source2 value and replaces the contents of this block. */ + template + AudioBlock& replaceWithSumOf (AudioBlock src1, AudioBlock src2) noexcept { replaceWithSumOfInternal (src1, src2); return *this; } + template + const AudioBlock& replaceWithSumOf (AudioBlock src1, AudioBlock src2) const noexcept { replaceWithSumOfInternal (src1, src2); return *this; } + + //============================================================================== + /** Subtracts a fixed value from the elements in this block. */ + AudioBlock& JUCE_VECTOR_CALLTYPE subtract (SampleType value) noexcept { subtractInternal (value); return *this; } + const AudioBlock& JUCE_VECTOR_CALLTYPE subtract (SampleType value) const noexcept { subtractInternal (value); return *this; } + + /** Subtracts the source values from the elements in this block. */ + template + AudioBlock& subtract (AudioBlock src) noexcept { subtractInternal (src); return *this; } + template + const AudioBlock& subtract (AudioBlock src) const noexcept { subtractInternal (src); return *this; } + + /** Subtracts a fixed value from each source value and replaces the contents of this block. */ + template + AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock src, SampleType value) noexcept { replaceWithDifferenceOfInternal (src, value); return *this; } + template + const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock src, SampleType value) const noexcept { replaceWithDifferenceOfInternal (src, value); return *this; } + + /** Subtracts each source2 value from the corresponding source1 value and replaces the contents of this block. */ + template + AudioBlock& replaceWithDifferenceOf (AudioBlock src1, AudioBlock src2) noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; } + template + const AudioBlock& replaceWithDifferenceOf (AudioBlock src1, AudioBlock src2) const noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; } + + //============================================================================== + /** Multiplies the elements in this block by a fixed value. */ + AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (SampleType value) noexcept { multiplyByInternal (value); return *this; } + const AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (SampleType value) const noexcept { multiplyByInternal (value); return *this; } + + /** Multiplies the elements in this block by the elements in the src block */ + template + AudioBlock& multiplyBy (AudioBlock src) noexcept { multiplyByInternal (src); return *this; } + template + const AudioBlock& multiplyBy (AudioBlock src) const noexcept { multiplyByInternal (src); return *this; } + + /** Replaces the elements in this block with the product of the elements in the source src block and a fixed value. */ + template + AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock src, SampleType value) noexcept { replaceWithProductOfInternal (src, value); return *this; } + template + const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock src, SampleType value) const noexcept { replaceWithProductOfInternal (src, value); return *this; } + + /** Replaces the elements in this block with the product of the elements in the src1 and scr2 blocks. */ + template + AudioBlock& replaceWithProductOf (AudioBlock src1, AudioBlock src2) noexcept { replaceWithProductOfInternal (src1, src2); return *this; } + template + const AudioBlock& replaceWithProductOf (AudioBlock src1, AudioBlock src2) const noexcept { replaceWithProductOfInternal (src1, src2); return *this; } + + //============================================================================== + /** Multiplies each channels of this block by a smoothly changing value. */ + template + AudioBlock& multiplyBy (SmoothedValue& value) noexcept { multiplyByInternal (value); return *this; } + template + const AudioBlock& multiplyBy (SmoothedValue& value) const noexcept { multiplyByInternal (value); return *this; } + + /** Replaces each channel of this block with the product of the src block and a smoothed value. */ + template + AudioBlock& replaceWithProductOf (AudioBlock src, SmoothedValue& value) noexcept { replaceWithProductOfInternal (src, value); return *this; } + template + const AudioBlock& replaceWithProductOf (AudioBlock src, SmoothedValue& value) const noexcept { replaceWithProductOfInternal (src, value); return *this; } + + //============================================================================== + /** Multiplies each value in src by a fixed value and adds the result to this block. */ + template + AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock src, SampleType factor) noexcept { addProductOfInternal (src, factor); return *this; } + template + const AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock src, SampleType factor) const noexcept { addProductOfInternal (src, factor); return *this; } + + /** Multiplies each value in srcA with the corresponding value in srcB and adds the result to this block. */ + template + AudioBlock& addProductOf (AudioBlock src1, AudioBlock src2) noexcept { addProductOfInternal (src1, src2); return *this; } + template + const AudioBlock& addProductOf (AudioBlock src1, AudioBlock src2) const noexcept { addProductOfInternal (src1, src2); return *this; } + + //============================================================================== + /** Negates each value of this block. */ + AudioBlock& negate() noexcept { negateInternal(); return *this; } + const AudioBlock& negate() const noexcept { negateInternal(); return *this; } + + /** Replaces the contents of this block with the negative of the values in the src block. */ + template + AudioBlock& replaceWithNegativeOf (AudioBlock src) noexcept { replaceWithNegativeOfInternal (src); return *this; } + template + const AudioBlock& replaceWithNegativeOf (AudioBlock src) const noexcept { replaceWithNegativeOfInternal (src); return *this; } + + /** Replaces the contents of this block with the absolute values of the src block. */ + template + AudioBlock& replaceWithAbsoluteValueOf (AudioBlock src) noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; } + template + const AudioBlock& replaceWithAbsoluteValueOf (AudioBlock src) const noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; } + + //============================================================================== + /** Replaces each element of this block with the minimum of the corresponding element of the source arrays. */ + template + AudioBlock& replaceWithMinOf (AudioBlock src1, AudioBlock src2) noexcept { replaceWithMinOfInternal (src1, src2); return *this; } + template + const AudioBlock& replaceWithMinOf (AudioBlock src1, AudioBlock src2) const noexcept { replaceWithMinOfInternal (src1, src2); return *this; } + + /** Replaces each element of this block with the maximum of the corresponding element of the source arrays. */ + template + AudioBlock& replaceWithMaxOf (AudioBlock src1, AudioBlock src2) noexcept { replaceWithMaxOfInternal (src1, src2); return *this; } + template + const AudioBlock& replaceWithMaxOf (AudioBlock src1, AudioBlock src2) const noexcept { replaceWithMaxOfInternal (src1, src2); return *this; } + + //============================================================================== + /** Finds the minimum and maximum value of the buffer. */ + Range::type> findMinAndMax() const noexcept + { + if (numChannels == 0) + return {}; + + auto n = static_cast (numSamples * sizeFactor); + auto minmax = FloatVectorOperations::findMinAndMax (getChannelPointer (0), n); + + for (size_t ch = 1; ch < numChannels; ++ch) + minmax = minmax.getUnionWith (FloatVectorOperations::findMinAndMax (getChannelPointer (ch), n)); + + return minmax; + } + + //============================================================================== + // Convenient operator wrappers. + AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (SampleType value) noexcept { return add (value); } + const AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (SampleType value) const noexcept { return add (value); } + + AudioBlock& operator+= (AudioBlock src) noexcept { return add (src); } + const AudioBlock& operator+= (AudioBlock src) const noexcept { return add (src); } + + AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (SampleType value) noexcept { return subtract (value); } + const AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (SampleType value) const noexcept { return subtract (value); } + + AudioBlock& operator-= (AudioBlock src) noexcept { return subtract (src); } + const AudioBlock& operator-= (AudioBlock src) const noexcept { return subtract (src); } + + AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (SampleType value) noexcept { return multiplyBy (value); } + const AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (SampleType value) const noexcept { return multiplyBy (value); } + + AudioBlock& operator*= (AudioBlock src) noexcept { return multiplyBy (src); } + const AudioBlock& operator*= (AudioBlock src) const noexcept { return multiplyBy (src); } + + template + AudioBlock& operator*= (SmoothedValue& value) noexcept { return multiplyBy (value); } + template + const AudioBlock& operator*= (SmoothedValue& value) const noexcept { return multiplyBy (value); } + + //============================================================================== + // This class can only be used with floating point types + static_assert (std::is_same, float>::value + || std::is_same, double>::value + #if JUCE_USE_SIMD + || std::is_same, SIMDRegister>::value + || std::is_same, SIMDRegister>::value + #endif + , "AudioBlock only supports single or double precision floating point types"); + + //============================================================================== + /** Applies a function to each value in an input block, putting the result into an output block. + The function supplied must take a SampleType as its parameter, and return a SampleType. + The two blocks must have the same number of channels and samples. + */ + template + static void process (AudioBlock inBlock, AudioBlock outBlock, FunctionType&& function) + { + auto len = inBlock.getNumSamples(); + auto numChans = inBlock.getNumChannels(); + + jassert (len == outBlock.getNumSamples()); + jassert (numChans == outBlock.getNumChannels()); + + for (ChannelCountType c = 0; c < numChans; ++c) + { + auto* src = inBlock.getChannelPointer (c); + auto* dst = outBlock.getChannelPointer (c); + + for (size_t i = 0; i < len; ++i) + dst[i] = function (src[i]); + } + } + +private: + //============================================================================== + void JUCE_VECTOR_CALLTYPE clearInternal() const noexcept { auto n = static_cast (numSamples * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::add (channelPtr (ch), value, n); + FloatVectorOperations::clear (getChannelPointer (ch), n); + } - return *this; + void JUCE_VECTOR_CALLTYPE fillInternal (SampleType value) const noexcept + { + auto n = static_cast (numSamples * sizeFactor); + + for (size_t ch = 0; ch < numChannels; ++ch) + FloatVectorOperations::fill (getChannelPointer (ch), value, n); + } + + template + void copyFromInternal (const AudioBlock& src) const noexcept + { + auto maxChannels = jmin (src.numChannels, numChannels); + auto n = static_cast (jmin (src.numSamples, numSamples) * sizeFactor); + + for (size_t ch = 0; ch < maxChannels; ++ch) + FloatVectorOperations::copy (getChannelPointer (ch), src.getChannelPointer (ch), n); + } + + template + void copyFromInternal (const AudioBuffer& src, size_t srcPos, size_t dstPos, size_t numElements) const + { + auto srclen = static_cast (src.getNumSamples()) / sizeFactor; + auto n = static_cast (jmin (srclen - srcPos, numSamples - dstPos, numElements) * sizeFactor); + auto maxChannels = jmin (static_cast (src.getNumChannels()), static_cast (numChannels)); + + for (size_t ch = 0; ch < maxChannels; ++ch) + FloatVectorOperations::copy (getChannelPointer (ch) + dstPos, + src.getReadPointer (static_cast (ch), + static_cast (srcPos * sizeFactor)), + n); + } + + void moveInternal (size_t srcPos, size_t dstPos, + size_t numElements = std::numeric_limits::max()) const noexcept + { + jassert (srcPos <= numSamples && dstPos <= numSamples); + auto len = jmin (numSamples - srcPos, numSamples - dstPos, numElements) * sizeof (SampleType); + + if (len != 0) + for (size_t ch = 0; ch < numChannels; ++ch) + ::memmove (getChannelPointer (ch) + dstPos, + getChannelPointer (ch) + srcPos, len); + } + + //============================================================================== + void JUCE_VECTOR_CALLTYPE addInternal (SampleType value) const noexcept + { + auto n = static_cast (numSamples * sizeFactor); + + for (size_t ch = 0; ch < numChannels; ++ch) + FloatVectorOperations::add (getChannelPointer (ch), value, n); } - /** Adds the source values to the receiver. */ template - forcedinline AudioBlock& add (AudioBlock src) noexcept + void addInternal (AudioBlock src) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::add (channelPtr (ch), src.channelPtr (ch), n); - - return *this; + FloatVectorOperations::add (getChannelPointer (ch), src.getChannelPointer (ch), n); } - /** Adds a fixed value to each source value and stores it in the destination array of the receiver. */ template - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE add (AudioBlock src, SampleType value) noexcept + void JUCE_VECTOR_CALLTYPE replaceWithSumOfInternal (AudioBlock src, SampleType value) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::add (channelPtr (ch), src.channelPtr (ch), value, n); - - return *this; + FloatVectorOperations::add (getChannelPointer (ch), src.getChannelPointer (ch), value, n); } - /** Adds each source1 value to the corresponding source2 value and stores it in the destination array of the receiver. */ template - forcedinline AudioBlock& add (AudioBlock src1, AudioBlock src2) noexcept + void replaceWithSumOfInternal (AudioBlock src1, AudioBlock src2) const noexcept { jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels); auto n = static_cast (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::add (channelPtr (ch), src1.channelPtr (ch), src2.getChannelPointer (ch), n); - - return *this; + FloatVectorOperations::add (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n); } - /** Subtracts a fixed value from the receiver. */ - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE subtract (SampleType value) noexcept + //============================================================================== + constexpr void JUCE_VECTOR_CALLTYPE subtractInternal (SampleType value) const noexcept { - return add (value * static_cast (-1.0)); + addInternal (value * static_cast (-1.0)); } - /** Subtracts the source values from the receiver. */ template - forcedinline AudioBlock& subtract (AudioBlock src) noexcept + void subtractInternal (AudioBlock src) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::subtract (channelPtr (ch), src.channelPtr (ch), n); - - return *this; + FloatVectorOperations::subtract (getChannelPointer (ch), src.getChannelPointer (ch), n); } - /** Subtracts a fixed value from each source value and stores it in the destination array of the receiver. */ template - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE subtract (AudioBlock src, SampleType value) noexcept + void JUCE_VECTOR_CALLTYPE replaceWithDifferenceOfInternal (AudioBlock src, SampleType value) const noexcept { - return add (src, static_cast (-1.0) * value); + replaceWithSumOfInternal (src, static_cast (-1.0) * value); } - /** Subtracts each source2 value from the corresponding source1 value and stores it in the destination array of the receiver. */ template - forcedinline AudioBlock& subtract (AudioBlock src1, AudioBlock src2) noexcept + void replaceWithDifferenceOfInternal (AudioBlock src1, AudioBlock src2) const noexcept { jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels); auto n = static_cast (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::subtract (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n); - - return *this; + FloatVectorOperations::subtract (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n); } - /** Multiplies a fixed value to the receiver. */ - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE multiply (SampleType value) noexcept + //============================================================================== + void JUCE_VECTOR_CALLTYPE multiplyByInternal (SampleType value) const noexcept { auto n = static_cast (numSamples * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::multiply (channelPtr (ch), value, n); - - return *this; + FloatVectorOperations::multiply (getChannelPointer (ch), value, n); } - /** Multiplies the source values to the receiver. */ template - forcedinline AudioBlock& multiply (AudioBlock src) noexcept + void multiplyByInternal (AudioBlock src) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::multiply (channelPtr (ch), src.channelPtr (ch), n); - - return *this; + FloatVectorOperations::multiply (getChannelPointer (ch), src.getChannelPointer (ch), n); } - /** Multiplies a fixed value to each source value and stores it in the destination array of the receiver. */ template - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE multiply (AudioBlock src, SampleType value) noexcept + void JUCE_VECTOR_CALLTYPE replaceWithProductOfInternal (AudioBlock src, SampleType value) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::multiply (channelPtr (ch), src.channelPtr (ch), value, n); - - return *this; + FloatVectorOperations::multiply (getChannelPointer (ch), src.getChannelPointer (ch), value, n); } - /** Multiplies each source1 value to the corresponding source2 value and stores it in the destination array of the receiver. */ template - forcedinline AudioBlock& multiply (AudioBlock src1, AudioBlock src2) noexcept + void replaceWithProductOfInternal (AudioBlock src1, AudioBlock src2) const noexcept { jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels); auto n = static_cast (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::multiply (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n); - - return *this; + FloatVectorOperations::multiply (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n); } - /** Multiplies all channels of the AudioBlock by a smoothly changing value and stores them . */ template - AudioBlock& multiply (SmoothedValue& value) noexcept + void multiplyByInternal (SmoothedValue& value) const noexcept { if (! value.isSmoothing()) { - *this *= value.getTargetValue(); + multiplyByInternal (value.getTargetValue()); } else { @@ -571,22 +751,19 @@ public: const auto scaler = value.getNextValue(); for (size_t ch = 0; ch < numChannels; ++ch) - channelPtr (ch)[i] *= scaler; + getChannelPointer (ch)[i] *= scaler; } } - - return *this; } - /** Multiplies all channels of the source by a smoothly changing value and stores them in the receiver. */ template - AudioBlock& multiply (AudioBlock src, SmoothedValue& value) noexcept + void replaceWithProductOfInternal (AudioBlock src, SmoothedValue& value) const noexcept { jassert (numChannels == src.numChannels); if (! value.isSmoothing()) { - multiply (src, value.getTargetValue()); + replaceWithProductOfInternal (src, value.getTargetValue()); } else { @@ -597,162 +774,79 @@ public: const auto scaler = value.getNextValue(); for (size_t ch = 0; ch < numChannels; ++ch) - channelPtr (ch)[i] = scaler * src.getChannelPointer (ch)[i]; + getChannelPointer (ch)[i] = scaler * src.getChannelPointer (ch)[i]; } } - - return *this; } - /** Multiplies each value in src with factor and adds the result to the receiver. */ + //============================================================================== template - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE addWithMultiply (AudioBlock src, SampleType factor) noexcept + void JUCE_VECTOR_CALLTYPE addProductOfInternal (AudioBlock src, SampleType factor) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::addWithMultiply (channelPtr (ch), src.channelPtr (ch), factor, n); - - return *this; + FloatVectorOperations::addWithMultiply (getChannelPointer (ch), src.getChannelPointer (ch), factor, n); } - /** Multiplies each value in srcA with the corresponding value in srcB and adds the result to the receiver. */ template - forcedinline AudioBlock& addWithMultiply (AudioBlock src1, AudioBlock src2) noexcept + void addProductOfInternal (AudioBlock src1, AudioBlock src2) const noexcept { jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels); auto n = static_cast (jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::addWithMultiply (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n); - - return *this; + FloatVectorOperations::addWithMultiply (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n); } - /** Negates each value of the receiver. */ - forcedinline AudioBlock& negate() noexcept + //============================================================================== + constexpr void negateInternal() const noexcept { - return multiply (static_cast (-1.0)); + multiplyByInternal (static_cast (-1.0)); } - /** Negates each value of source and stores it in the receiver. */ template - forcedinline AudioBlock& replaceWithNegativeOf (AudioBlock src) noexcept + void replaceWithNegativeOfInternal (AudioBlock src) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::negate (channelPtr (ch), src.channelPtr (ch), n); - - return *this; + FloatVectorOperations::negate (getChannelPointer (ch), src.getChannelPointer (ch), n); } - /** Takes the absolute value of each element of src and stores it inside the receiver. */ template - forcedinline AudioBlock& replaceWithAbsoluteValueOf (AudioBlock src) noexcept + void replaceWithAbsoluteValueOfInternal (AudioBlock src) const noexcept { jassert (numChannels == src.numChannels); auto n = static_cast (jmin (numSamples, src.numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::abs (channelPtr (ch), src.channelPtr (ch), n); - - return *this; + FloatVectorOperations::abs (getChannelPointer (ch), src.getChannelPointer (ch), n); } - /** Each element of receiver will be the minimum of the corresponding element of the source arrays. */ + //============================================================================== template - forcedinline AudioBlock& min (AudioBlock src1, AudioBlock src2) noexcept + void replaceWithMinOfInternal (AudioBlock src1, AudioBlock src2) const noexcept { jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels); auto n = static_cast (jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::min (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n); - - return *this; + FloatVectorOperations::min (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n); } - /** Each element of the receiver will be the maximum of the corresponding element of the source arrays. */ template - forcedinline AudioBlock& max (AudioBlock src1, AudioBlock src2) noexcept + void replaceWithMaxOfInternal (AudioBlock src1, AudioBlock src2) const noexcept { jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels); auto n = static_cast (jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor); for (size_t ch = 0; ch < numChannels; ++ch) - FloatVectorOperations::max (channelPtr (ch), src1.channelPtr (ch), src2.channelPtr (ch), n); - - return *this; + FloatVectorOperations::max (getChannelPointer (ch), src1.getChannelPointer (ch), src2.getChannelPointer (ch), n); } - /** Finds the minimum and maximum value of the buffer. */ - forcedinline Range findMinAndMax() const noexcept - { - if (numChannels == 0) - return {}; - - auto n = static_cast (numSamples * sizeFactor); - auto minmax = FloatVectorOperations::findMinAndMax (channelPtr (0), n); - - for (size_t ch = 1; ch < numChannels; ++ch) - minmax = minmax.getUnionWith (FloatVectorOperations::findMinAndMax (channelPtr (ch), n)); - - return minmax; - } - - //============================================================================== - // convenient operator wrappers - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (SampleType src) noexcept { return add (src); } - forcedinline AudioBlock& operator+= (AudioBlock src) noexcept { return add (src); } - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (SampleType src) noexcept { return subtract (src); } - forcedinline AudioBlock& operator-= (AudioBlock src) noexcept { return subtract (src); } - forcedinline AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (SampleType src) noexcept { return multiply (src); } - forcedinline AudioBlock& operator*= (AudioBlock src) noexcept { return multiply (src); } - template - forcedinline AudioBlock& operator*= (SmoothedValue& value) noexcept { return multiply (value); } - - //============================================================================== - // This class can only be used with floating point types - static_assert (std::is_same, float>::value - || std::is_same, double>::value - #if JUCE_USE_SIMD - || std::is_same, SIMDRegister>::value - || std::is_same, SIMDRegister>::value - #endif - , "AudioBlock only supports single or double precision floating point types"); - - //============================================================================== - /** Applies a function to each value in an input block, putting the result into an output block. - The function supplied must take a SampleType as its parameter, and return a SampleType. - The two blocks must have the same number of channels and samples. - */ - template - static void process (AudioBlock inBlock, AudioBlock outBlock, FunctionType&& function) - { - auto len = inBlock.getNumSamples(); - auto numChans = inBlock.getNumChannels(); - - jassert (len == outBlock.getNumSamples()); - jassert (numChans == outBlock.getNumChannels()); - - for (ChannelCountType c = 0; c < numChans; ++c) - { - auto* src = inBlock.getChannelPointer (c); - auto* dst = outBlock.getChannelPointer (c); - - for (size_t i = 0; i < len; ++i) - dst[i] = function (src[i]); - } - } - -private: - //============================================================================== - NumericType* channelPtr (size_t ch) noexcept { return reinterpret_cast (getChannelPointer (ch)); } - const NumericType* channelPtr (size_t ch) const noexcept { return reinterpret_cast (getChannelPointer (ch)); } - //============================================================================== using ChannelCountType = unsigned int; diff --git a/modules/juce_dsp/containers/juce_AudioBlock_test.cpp b/modules/juce_dsp/containers/juce_AudioBlock_test.cpp new file mode 100644 index 00000000..f0192e8a --- /dev/null +++ b/modules/juce_dsp/containers/juce_AudioBlock_test.cpp @@ -0,0 +1,342 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2017 - ROLI Ltd. + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 5 End-User License + Agreement and JUCE 5 Privacy Policy (both updated and effective as of the + 27th April 2017). + + End User License Agreement: www.juce.com/juce-5-licence + Privacy Policy: www.juce.com/juce-5-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +class AudioBlockUnitTests : public UnitTest +{ +public: + AudioBlockUnitTests() + : UnitTest ("AudioBlock", UnitTestCategories::dsp) + {} + + void runTest() override + { + beginTest ("Equality"); + { + expect (block == block); + expect (block != otherBlock); + } + + beginTest ("Constructors"); + { + expect (block == AudioBlock (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) data.getNumSamples())); + expect (block == AudioBlock (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) 0, (size_t) data.getNumSamples())); + expect (block == AudioBlock (block)); + + expect (block == AudioBlock (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) data.getNumSamples())); + expect (block == AudioBlock (data.getArrayOfWritePointers(), (size_t) data.getNumChannels(), (size_t) 0, (size_t) data.getNumSamples())); + expect (block == AudioBlock (block)); + } + + beginTest ("Swap"); + { + resetBlocks(); + + expect (block != otherBlock); + expectEquals (block.getSample (0, 0), 1.0f); + expectEquals (block.getSample (0, 4), 5.0f); + expectEquals (otherBlock.getSample (0, 0), -1.0f); + expectEquals (otherBlock.getSample (0, 3), -4.0f); + + block.swap (otherBlock); + + expect (block != otherBlock); + expectEquals (otherBlock.getSample (0, 0), 1.0f); + expectEquals (otherBlock.getSample (0, 4), 5.0f); + expectEquals (block.getSample (0, 0), -1.0f); + expectEquals (block.getSample (0, 3), -4.0f); + } + + beginTest ("Getters and setters"); + { + resetBlocks(); + + expectEquals ((int) block.getNumChannels(), data.getNumChannels()); + expectEquals ((int) block.getNumSamples(), data.getNumSamples()); + + expectEquals (block.getChannelPointer (0)[2], 3.0f); + block.getChannelPointer (0)[2] = 999.0f; + expectEquals (block.getChannelPointer (0)[2], 999.0f); + + expectEquals (block.getSample (0, 4), 5.0f); + expectEquals (block.getSample (1, 4), 11.0f); + + expectEquals (block.getSingleChannelBlock (1).getSample (0, 3), block.getSample (1, 3)); + + expectEquals (block.getSubsetChannelBlock (0, 2).getSample (1, 3), block.getSample (1, 3)); + expectEquals (block.getSubsetChannelBlock (1, 1).getSample (0, 3), block.getSample (1, 3)); + + block.setSample (1, 1, 777.0f); + expectEquals (block.getSample (1, 1), 777.0f); + + block.addSample (1, 1, 1.0f); + expectEquals (block.getSample (1, 1), 778.0f); + } + + beginTest ("Copying"); + { + block.clear(); + expectEquals (block.getSample (0, 2), 0.0f); + expectEquals (block.getSample (1, 4), 0.0f); + + block.fill (456.0f); + expectEquals (block.getSample (0, 2), 456.0f); + expectEquals (block.getSample (1, 4), 456.0f); + + block.copyFrom (otherBlock); + expect (block != otherBlock); + expectEquals (block.getSample (0, 2), otherBlock.getSample (0, 2)); + expectEquals (block.getSample (1, 4), otherBlock.getSample (1, 4)); + + resetBlocks(); + + AudioBuffer otherBuffer ((int) block.getNumChannels(), (int) block.getNumSamples()); + otherBlock.copyTo (otherBuffer); + expectEquals (otherBlock.getSample (0, 2), otherBuffer.getSample (0, 2)); + expectEquals (otherBlock.getSample (1, 4), otherBuffer.getSample (1, 4)); + + block.copyFrom (otherBuffer); + expectEquals (block.getSample (0, 2), otherBlock.getSample (0, 2)); + expectEquals (block.getSample (1, 4), otherBlock.getSample (1, 4)); + + float testSample1 = block.getSample (0, 2); + float testSample2 = block.getSample (1, 3); + expect (testSample1 != block.getSample (0, 4)); + expect (testSample2 != block.getSample (1, 5)); + block.move (0, 2); + expectEquals (block.getSample (0, 4), testSample1); + expectEquals (block.getSample (1, 5), testSample2); + } + + beginTest ("Addition"); + { + resetBlocks(); + + block.add (15.0f); + expectEquals (block.getSample (0, 4), 20.0f); + expectEquals (block.getSample (1, 4), 26.0f); + + block.add (otherBlock); + expectEquals (block.getSample (0, 4), 15.0f); + expectEquals (block.getSample (1, 4), 15.0f); + + block.replaceWithSumOf (otherBlock, 9.0f); + expectEquals (block.getSample (0, 4), 4.0f); + expectEquals (block.getSample (1, 4), -2.0f); + + resetBlocks(); + + block.replaceWithSumOf (block, otherBlock); + expectEquals (block.getSample (0, 4), 0.0f); + expectEquals (block.getSample (1, 4), 0.0f); + } + + beginTest ("Subtraction"); + { + resetBlocks(); + + block.subtract (15.0f); + expectEquals (block.getSample (0, 4), -10.0f); + expectEquals (block.getSample (1, 4), -4.0f); + + block.subtract (otherBlock); + expectEquals (block.getSample (0, 4), -5.0f); + expectEquals (block.getSample (1, 4), 7.0f); + + block.replaceWithDifferenceOf (otherBlock, 9.0f); + expectEquals (block.getSample (0, 4), -14.0f); + expectEquals (block.getSample (1, 4), -20.0f); + + resetBlocks(); + + block.replaceWithDifferenceOf (block, otherBlock); + expectEquals (block.getSample (0, 4), 10.0f); + expectEquals (block.getSample (1, 4), 22.0f); + } + + beginTest ("Multiplication"); + { + resetBlocks(); + + block.multiplyBy (10.0f); + expectEquals (block.getSample (0, 4), 50.0f); + expectEquals (block.getSample (1, 4), 110.0f); + + block.multiplyBy (otherBlock); + expectEquals (block.getSample (0, 4), -250.0f); + expectEquals (block.getSample (1, 4), -1210.0f); + + block.replaceWithProductOf (otherBlock, 3.0f); + expectEquals (block.getSample (0, 4), -15.0f); + expectEquals (block.getSample (1, 4), -33.0f); + + resetBlocks(); + + block.replaceWithProductOf (block, otherBlock); + expectEquals (block.getSample (0, 4), -25.0f); + expectEquals (block.getSample (1, 4), -121.0f); + } + + beginTest ("Smoothing"); + { + block.fill (1.0f); + SmoothedValue sv { 1.0f }; + sv.reset (1, 4); + sv.setTargetValue (0.0f); + + block.multiplyBy (sv); + expect (block.getSample (0, 2) < 1.0f); + expect (block.getSample (1, 2) < 1.0f); + expect (block.getSample (0, 2) > 0.0f); + expect (block.getSample (1, 2) > 0.0f); + expectEquals (block.getSample (0, 5), 0.0f); + expectEquals (block.getSample (1, 5), 0.0f); + + sv.setCurrentAndTargetValue (-1.0f); + sv.setTargetValue (0.0f); + otherBlock.fill (-1.0f); + block.replaceWithProductOf (otherBlock, sv); + expect (block.getSample (0, 2) < 1.0f); + expect (block.getSample (1, 2) < 1.0f); + expect (block.getSample (0, 2) > 0.0f); + expect (block.getSample (1, 2) > 0.0f); + expectEquals (block.getSample (0, 5), 0.0f); + expectEquals (block.getSample (1, 5), 0.0f); + } + + beginTest ("Multiply add"); + { + resetBlocks(); + + block.addProductOf (otherBlock, -1.0f); + expectEquals (block.getSample (0, 4), 10.0f); + expectEquals (block.getSample (1, 4), 22.0f); + + block.addProductOf (otherBlock, otherBlock); + expectEquals (block.getSample (0, 4), 35.0f); + expectEquals (block.getSample (1, 4), 143.0f); + } + + beginTest ("Negative abs min max"); + { + resetBlocks(); + otherBlock.negate(); + + block.add (otherBlock); + expectEquals (block.getSample (0, 4), 10.0f); + expectEquals (block.getSample (1, 4), 22.0f); + + block.replaceWithNegativeOf (otherBlock); + expectEquals (block.getSample (0, 4), -5.0f); + expectEquals (block.getSample (1, 4), -11.0f); + + block.clear(); + otherBlock.negate(); + block.replaceWithAbsoluteValueOf (otherBlock); + expectEquals (block.getSample (0, 4), 5.0f); + expectEquals (block.getSample (1, 4), 11.0f); + + resetBlocks(); + block.replaceWithMinOf (block, otherBlock); + expectEquals (block.getSample (0, 4), -5.0f); + expectEquals (block.getSample (1, 4), -11.0f); + + resetBlocks(); + block.replaceWithMaxOf (block, otherBlock); + expectEquals (block.getSample (0, 4), 5.0f); + expectEquals (block.getSample (1, 4), 11.0f); + + resetBlocks(); + auto range = block.findMinAndMax(); + expectEquals (range.getStart(), 1.0f); + expectEquals (range.getEnd(), 12.0f); + } + + beginTest ("Operators"); + { + resetBlocks(); + block += 10.0f; + expectEquals (block.getSample (0, 4), 15.0f); + expectEquals (block.getSample (1, 4), 21.0f); + block += otherBlock; + expectEquals (block.getSample (0, 4), 10.0f); + expectEquals (block.getSample (1, 4), 10.0f); + + resetBlocks(); + block -= 10.0f; + expectEquals (block.getSample (0, 4), -5.0f); + expectEquals (block.getSample (1, 4), 1.0f); + block -= otherBlock; + expectEquals (block.getSample (0, 4), 0.0f); + expectEquals (block.getSample (1, 4), 12.0f); + + resetBlocks(); + block *= 10.0f; + expectEquals (block.getSample (0, 4), 50.0f); + expectEquals (block.getSample (1, 4), 110.0f); + block *= otherBlock; + expectEquals (block.getSample (0, 4), -250.0f); + expectEquals (block.getSample (1, 4), -1210.0f); + } + + beginTest ("Process"); + { + resetBlocks(); + AudioBlock::process (block, otherBlock, [](float x) { return x + 1.0f; }); + expectEquals (otherBlock.getSample (0, 4), 6.0f); + expectEquals (otherBlock.getSample (1, 4), 12.0f); + } + } + +private: + AudioBuffer data { 2, 6 }, otherData { 2, 6 }; + AudioBlock block { data }, otherBlock { otherData }; + + void resetBlocks() + { + auto value = 1.0f; + + for (size_t c = 0; c < block.getNumChannels(); ++c) + { + for (size_t i = 0; i < block.getNumSamples(); ++i) + { + block.setSample ((int) c, (int) i, value); + value += 1.0f; + } + } + + otherBlock.replaceWithNegativeOf (block); + } +}; + +static AudioBlockUnitTests audioBlockUnitTests; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/frequency/juce_Convolution.cpp b/modules/juce_dsp/frequency/juce_Convolution.cpp index f0b5ab2f..3288651c 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.cpp +++ b/modules/juce_dsp/frequency/juce_Convolution.cpp @@ -768,7 +768,7 @@ struct Convolution::Pimpl : private Thread } if (input.getNumChannels() > 1 && currentInfo.wantsStereo == false) - output.getSingleChannelBlock (1).copy (output.getSingleChannelBlock (0)); + output.getSingleChannelBlock (1).copyFrom (output.getSingleChannelBlock (0)); } //============================================================================== @@ -1212,7 +1212,7 @@ void Convolution::processSamples (const AudioBlock& input, AudioBlo if (volumeDry[0].isSmoothing()) { - dry.copy (input); + dry.copyFrom (input); for (size_t channel = 0; channel < numChannels; ++channel) volumeDry[channel].applyGain (dry.getChannelPointer (channel), (int) numSamples); diff --git a/modules/juce_dsp/juce_dsp.cpp b/modules/juce_dsp/juce_dsp.cpp index 56748f14..0d61a417 100644 --- a/modules/juce_dsp/juce_dsp.cpp +++ b/modules/juce_dsp/juce_dsp.cpp @@ -89,6 +89,7 @@ #include "containers/juce_SIMDRegister_test.cpp" #endif + #include "containers/juce_AudioBlock_test.cpp" #include "frequency/juce_FFT_test.cpp" #include "processors/juce_FIRFilter_test.cpp" #endif diff --git a/modules/juce_dsp/juce_dsp.h b/modules/juce_dsp/juce_dsp.h index 2f446d1d..68abb03e 100644 --- a/modules/juce_dsp/juce_dsp.h +++ b/modules/juce_dsp/juce_dsp.h @@ -36,7 +36,7 @@ ID: juce_dsp vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE DSP classes description: Classes for audio buffer manipulation, digital audio processing, filtering, oversampling, fast math functions etc. website: http://www.juce.com/juce diff --git a/modules/juce_dsp/processors/juce_Bias.h b/modules/juce_dsp/processors/juce_Bias.h index 4348cdb3..a279f617 100644 --- a/modules/juce_dsp/processors/juce_Bias.h +++ b/modules/juce_dsp/processors/juce_Bias.h @@ -114,7 +114,7 @@ public: bias.skip (static_cast (len)); if (context.usesSeparateInputAndOutputBlocks()) - outBlock.copy (inBlock); + outBlock.copyFrom (inBlock); return; } diff --git a/modules/juce_dsp/processors/juce_Gain.h b/modules/juce_dsp/processors/juce_Gain.h index 3c542b57..21a3391d 100644 --- a/modules/juce_dsp/processors/juce_Gain.h +++ b/modules/juce_dsp/processors/juce_Gain.h @@ -110,7 +110,7 @@ public: gain.skip (static_cast (len)); if (context.usesSeparateInputAndOutputBlocks()) - outBlock.copy (inBlock); + outBlock.copyFrom (inBlock); return; } diff --git a/modules/juce_dsp/processors/juce_LadderFilter.h b/modules/juce_dsp/processors/juce_LadderFilter.h index 8b38aaf7..f3f302d4 100644 --- a/modules/juce_dsp/processors/juce_LadderFilter.h +++ b/modules/juce_dsp/processors/juce_LadderFilter.h @@ -92,7 +92,7 @@ public: if (! enabled || context.isBypassed) { - outputBlock.copy (inputBlock); + outputBlock.copyFrom (inputBlock); return; } diff --git a/modules/juce_dsp/processors/juce_Oversampling.cpp b/modules/juce_dsp/processors/juce_Oversampling.cpp index 109047b5..a7b1c8f6 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.cpp +++ b/modules/juce_dsp/processors/juce_Oversampling.cpp @@ -38,7 +38,7 @@ struct Oversampling::OversamplingStage OversamplingStage (size_t numChans, size_t newFactor) : numChannels (numChans), factor (newFactor) {} virtual ~OversamplingStage() {} - //=============================================================================== + //============================================================================== virtual SampleType getLatencyInSamples() = 0; virtual void initProcessing (size_t maximumNumberOfSamplesBeforeOversampling) @@ -66,7 +66,7 @@ struct Oversampling::OversamplingStage }; -//=============================================================================== +//============================================================================== /** Dummy oversampling stage class which simply copies and pastes the input signal, which could be equivalent to a "one time" oversampling processing. */ @@ -77,7 +77,7 @@ struct OversamplingDummy : public Oversampling::OversamplingStage OversamplingDummy (size_t numChans) : ParentType (numChans, 1) {} - //=============================================================================== + //============================================================================== SampleType getLatencyInSamples() override { return 0; @@ -98,13 +98,13 @@ struct OversamplingDummy : public Oversampling::OversamplingStage jassert (outputBlock.getNumChannels() <= static_cast (ParentType::buffer.getNumChannels())); jassert (outputBlock.getNumSamples() * ParentType::factor <= static_cast (ParentType::buffer.getNumSamples())); - outputBlock.copy (ParentType::getProcessedSamples (outputBlock.getNumSamples())); + outputBlock.copyFrom (ParentType::getProcessedSamples (outputBlock.getNumSamples())); } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OversamplingDummy) }; -//=============================================================================== +//============================================================================== /** Oversampling stage class performing 2 times oversampling using the Filter Design FIR Equiripple method. The resulting filter is linear phase, symmetric, and has every two samples but the middle one equal to zero, @@ -138,7 +138,7 @@ struct Oversampling2TimesEquirippleFIR : public Oversampling::Overs position.resize (static_cast (this->numChannels)); } - //=============================================================================== + //============================================================================== SampleType getLatencyInSamples() override { return static_cast (coefficientsUp.getFilterOrder() + coefficientsDown.getFilterOrder()) * 0.5f; @@ -247,17 +247,17 @@ struct Oversampling2TimesEquirippleFIR : public Oversampling::Overs } private: - //=============================================================================== + //============================================================================== dsp::FIR::Coefficients coefficientsUp, coefficientsDown; AudioBuffer stateUp, stateDown, stateDown2; Array position; - //=============================================================================== + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling2TimesEquirippleFIR) }; -//=============================================================================== +//============================================================================== /** Oversampling stage class performing 2 times oversampling using the Filter Design IIR Polyphase Allpass Cascaded method. The resulting filter is minimum phase, and provided with a method to get the exact resulting latency. @@ -299,7 +299,7 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling::Oversa delayDown.resize (static_cast (this->numChannels)); } - //=============================================================================== + //============================================================================== SampleType getLatencyInSamples() override { return latency; @@ -453,7 +453,7 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling::Oversa } private: - //=============================================================================== + //============================================================================== /** This function calculates the equivalent high order IIR filter of a given polyphase cascaded allpass filters structure. */ @@ -515,19 +515,19 @@ private: return coeffs; } - //=============================================================================== + //============================================================================== Array coefficientsUp, coefficientsDown; SampleType latency; AudioBuffer v1Up, v1Down; Array delayDown; - //=============================================================================== + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling2TimesPolyphaseIIR) }; -//=============================================================================== +//============================================================================== template Oversampling::Oversampling (size_t newNumChannels) : numChannels (newNumChannels) @@ -590,7 +590,7 @@ Oversampling::~Oversampling() stages.clear(); } -//=============================================================================== +//============================================================================== template void Oversampling::addDummyOversamplingStage() { @@ -627,7 +627,7 @@ void Oversampling::clearOversamplingStages() factorOversampling = 1u; } -//=============================================================================== +//============================================================================== template SampleType Oversampling::getLatencyInSamples() noexcept { @@ -649,7 +649,7 @@ size_t Oversampling::getOversamplingFactor() noexcept return factorOversampling; } -//=============================================================================== +//============================================================================== template void Oversampling::initProcessing (size_t maximumNumberOfSamplesBeforeOversampling) { diff --git a/modules/juce_dsp/processors/juce_Oversampling.h b/modules/juce_dsp/processors/juce_Oversampling.h index 7c428180..e4fbb9db 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.h +++ b/modules/juce_dsp/processors/juce_Oversampling.h @@ -29,7 +29,7 @@ namespace juce namespace dsp { -//=============================================================================== +//============================================================================== /** A processing class performing multi-channel oversampling. @@ -65,7 +65,7 @@ public: numFilterTypes }; - //=============================================================================== + //============================================================================== /** Constructor of the oversampling class. All the processing parameters must be provided at the creation of the oversampling object. @@ -96,7 +96,7 @@ public: /** Destructor. */ ~Oversampling(); - //=============================================================================== + //============================================================================== /** Returns the latency in samples of the whole processing. Use this information in your main processor to compensate the additional latency involved with the oversampling, for example with a dry / wet functionality, and to report @@ -110,7 +110,7 @@ public: /** Returns the current oversampling factor. */ size_t getOversamplingFactor() noexcept; - //=============================================================================== + //============================================================================== /** Must be called before any processing, to set the buffer sizes of the internal buffers of the oversampling processing. */ @@ -135,7 +135,7 @@ public: */ void processSamplesDown (dsp::AudioBlock& outputBlock) noexcept; - //=============================================================================== + //============================================================================== /** Adds a new oversampling stage to the Oversampling class, multiplying the current oversampling factor by two. This is used with the default constructor to create custom oversampling chains, requiring a call to the @@ -179,7 +179,7 @@ public: */ void clearOversamplingStages(); - //=============================================================================== + //============================================================================== size_t factorOversampling = 1; size_t numChannels = 1; @@ -188,11 +188,11 @@ public: #endif private: - //=============================================================================== + //============================================================================== OwnedArray stages; bool isReady = false; - //=============================================================================== + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling) }; diff --git a/modules/juce_dsp/processors/juce_Reverb.h b/modules/juce_dsp/processors/juce_Reverb.h index a2ff3953..3e75a55b 100644 --- a/modules/juce_dsp/processors/juce_Reverb.h +++ b/modules/juce_dsp/processors/juce_Reverb.h @@ -85,7 +85,7 @@ public: jassert (inputBlock.getNumSamples() == numSamples); - outputBlock.copy (inputBlock); + outputBlock.copyFrom (inputBlock); if (! enabled || context.isBypassed) return; diff --git a/modules/juce_dsp/processors/juce_WaveShaper.h b/modules/juce_dsp/processors/juce_WaveShaper.h index f93151d1..8a2c624a 100644 --- a/modules/juce_dsp/processors/juce_WaveShaper.h +++ b/modules/juce_dsp/processors/juce_WaveShaper.h @@ -58,7 +58,7 @@ struct WaveShaper if (context.isBypassed) { if (context.usesSeparateInputAndOutputBlocks()) - context.getOutputBlock().copy (context.getInputBlock()); + context.getOutputBlock().copyFrom (context.getInputBlock()); } else { diff --git a/modules/juce_events/juce_events.h b/modules/juce_events/juce_events.h index 92fecfee..078c50dc 100644 --- a/modules/juce_events/juce_events.h +++ b/modules/juce_events/juce_events.h @@ -31,7 +31,7 @@ ID: juce_events vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE message and event handling classes description: Classes for running an application's main event loop and sending/receiving messages, timers, etc. website: http://www.juce.com/juce diff --git a/modules/juce_events/messages/juce_ApplicationBase.h b/modules/juce_events/messages/juce_ApplicationBase.h index a5f0260c..1b286ca6 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.h +++ b/modules/juce_events/messages/juce_ApplicationBase.h @@ -206,10 +206,17 @@ public: virtual void memoryWarningReceived() { jassertfalse; } //============================================================================== - /** Override this method to be informed when the back button is pressed on a device. + /** This will be called when the back button on a device is pressed. The return value + should be used to indicate whether the back button event has been handled by + the application, for example if you want to implement custom navigation instead + of the standard behaviour on Android. + This is currently only implemented on Android devices. + + @returns true if the event has been handled, or false if the default OS + behaviour should happen */ - virtual void backButtonPressed() {} + virtual bool backButtonPressed() { return false; } //============================================================================== /** Signals that the main message loop should stop and the application should terminate. diff --git a/modules/juce_events/messages/juce_MessageManager.cpp b/modules/juce_events/messages/juce_MessageManager.cpp index 8904f384..726554a9 100644 --- a/modules/juce_events/messages/juce_MessageManager.cpp +++ b/modules/juce_events/messages/juce_MessageManager.cpp @@ -184,16 +184,16 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func return nullptr; } -void MessageManager::callAsync (std::function fn) +bool MessageManager::callAsync (std::function fn) { struct AsyncCallInvoker : public MessageBase { - AsyncCallInvoker (std::function f) : callback (std::move (f)) { post(); } + AsyncCallInvoker (std::function f) : callback (std::move (f)) {} void messageCallback() override { callback(); } std::function callback; }; - new AsyncCallInvoker (std::move (fn)); + return (new AsyncCallInvoker (std::move (fn)))->post(); } //============================================================================== diff --git a/modules/juce_events/messages/juce_MessageManager.h b/modules/juce_events/messages/juce_MessageManager.h index b9051321..fd5e1013 100644 --- a/modules/juce_events/messages/juce_MessageManager.h +++ b/modules/juce_events/messages/juce_MessageManager.h @@ -94,8 +94,12 @@ public: #endif //============================================================================== - /** Asynchronously invokes a function or C++11 lambda on the message thread. */ - static void callAsync (std::function functionToCall); + /** Asynchronously invokes a function or C++11 lambda on the message thread. + + @returns true if the message was successfully posted to the message queue, + or false otherwise. + */ + static bool callAsync (std::function functionToCall); /** Calls a function using the message-thread. diff --git a/modules/juce_events/native/juce_linux_EventLoop.h b/modules/juce_events/native/juce_linux_EventLoop.h index cb7aded8..4aac0967 100644 --- a/modules/juce_events/native/juce_linux_EventLoop.h +++ b/modules/juce_events/native/juce_linux_EventLoop.h @@ -34,8 +34,11 @@ namespace LinuxEventLoop @param fd the file descriptor to be monitored @param readCallback a callback that will be called when the file descriptor has data to read. The file descriptor will be passed as an argument + @param eventMask a bit mask specifying the events you are interested in for the + file descriptor. The possible values for this are defined in + */ - void registerFdCallback (int fd, std::function readCallback); + void registerFdCallback (int fd, std::function readCallback, short eventMask = 1 /*POLLIN*/); /** Unregisters a previously registered file descriptor. diff --git a/modules/juce_events/native/juce_linux_Messaging.cpp b/modules/juce_events/native/juce_linux_Messaging.cpp index 9f20e95b..7287d6c4 100644 --- a/modules/juce_events/native/juce_linux_Messaging.cpp +++ b/modules/juce_events/native/juce_linux_Messaging.cpp @@ -20,8 +20,6 @@ ============================================================================== */ -#include - namespace juce { @@ -38,7 +36,7 @@ public: LinuxEventLoop::registerFdCallback (getReadHandle(), [this] (int fd) { - if (auto msg = popNextMessage (fd)) + while (auto msg = popNextMessage (fd)) { JUCE_TRY { @@ -77,7 +75,7 @@ public: } //============================================================================== - JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (InternalMessageQueue) + JUCE_DECLARE_SINGLETON (InternalMessageQueue, false) private: CriticalSection lock; @@ -119,12 +117,12 @@ public: fdReadCallbacks.reserve (8); } - void registerFdCallback (int fd, std::function&& cb) + void registerFdCallback (int fd, std::function&& cb, short eventMask) { const ScopedLock sl (lock); fdReadCallbacks.push_back ({ fd, std::move (cb) }); - pfds.push_back ({ fd, POLLIN, 0 }); + pfds.push_back ({ fd, eventMask, 0 }); } void unregisterFdCallback (int fd) @@ -183,7 +181,7 @@ public: } //============================================================================== - JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (InternalRunLoop) + JUCE_DECLARE_SINGLETON (InternalRunLoop, false) private: CriticalSection lock; @@ -273,10 +271,10 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMes } //============================================================================== -void LinuxEventLoop::registerFdCallback (int fd, std::function readCallback) +void LinuxEventLoop::registerFdCallback (int fd, std::function readCallback, short eventMask) { if (auto* runLoop = InternalRunLoop::getInstanceWithoutCreating()) - runLoop->registerFdCallback (fd, std::move (readCallback)); + runLoop->registerFdCallback (fd, std::move (readCallback), eventMask); } void LinuxEventLoop::unregisterFdCallback (int fd) diff --git a/modules/juce_graphics/contexts/juce_GraphicsContext.h b/modules/juce_graphics/contexts/juce_GraphicsContext.h index 5b503f0a..95b5f257 100644 --- a/modules/juce_graphics/contexts/juce_GraphicsContext.h +++ b/modules/juce_graphics/contexts/juce_GraphicsContext.h @@ -195,7 +195,7 @@ public: /** Tries to draw a text string inside a given space. This does its best to make the given text readable within the specified rectangle, - so it useful for labelling things. + so it's useful for labelling things. If the text is too big, it'll be squashed horizontally or broken over multiple lines if the maximumLinesToUse value allows this. If the text just won't fit into the space, @@ -220,7 +220,7 @@ public: /** Tries to draw a text string inside a given space. This does its best to make the given text readable within the specified rectangle, - so it useful for labelling things. + so it's useful for labelling things. If the text is too big, it'll be squashed horizontally or broken over multiple lines if the maximumLinesToUse value allows this. If the text just won't fit into the space, diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.h b/modules/juce_graphics/fonts/juce_GlyphArrangement.h index 8e29d40d..7aa7e807 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.h +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.h @@ -202,7 +202,7 @@ public: /** Tries to fit some text within a given space. This does its best to make the given text readable within the specified rectangle, - so it useful for labelling things. + so it's useful for labelling things. If the text is too big, it'll be squashed horizontally or broken over multiple lines if the maximumLinesToUse value allows this. If the text just won't fit into the space, diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index 1591490b..8b2444cf 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -617,66 +617,4 @@ void TextLayout::recalculateSize() } } -//============================================================================== -#if JUCE_UNIT_TESTS - -struct TextLayoutTests : public UnitTest -{ - TextLayoutTests() - : UnitTest ("Text Layout", UnitTestCategories::text) - {} - - static TextLayout createLayout (StringRef text, float width) - { - Font fontToUse (12.0f); - - AttributedString string (text); - string.setFont (std::move (fontToUse)); - - TextLayout layout; - layout.createLayout (std::move (string), width); - - return layout; - } - - void testLineBreaks (const String& line, float width, const StringArray& expected) - { - const auto layout = createLayout (line, width); - - beginTest ("A line is split into expected pieces"); - { - expectEquals (layout.getNumLines(), expected.size()); - - const auto limit = jmin (layout.getNumLines(), expected.size()); - - for (int i = 0; i != limit; ++i) - expectEquals (substring (line, layout.getLine (i).stringRange), expected[i]); - } - } - - void runTest() override - { - const String shortLine ("hello world"); - testLineBreaks (shortLine, 1.0e7f, { shortLine }); - - testLineBreaks ("this line should be split", - 60.0f, - { "this line ", - "should be ", - "split" }); - - testLineBreaks ("these\nlines \nhave\n weird \n spacing ", - 80.0f, - { "these\n", - "lines \n", - "have\n", - " weird \n", - " spacing " }); - } -}; - -static TextLayoutTests textLayoutTests; - -#endif - } // namespace juce diff --git a/modules/juce_graphics/geometry/juce_RectangleList.h b/modules/juce_graphics/geometry/juce_RectangleList.h index f6e0b993..81bd2f5e 100644 --- a/modules/juce_graphics/geometry/juce_RectangleList.h +++ b/modules/juce_graphics/geometry/juce_RectangleList.h @@ -386,7 +386,7 @@ public: destRegion.clear(); if (! rect.isEmpty()) - for (auto& r : rects) + for (auto r : rects) if (rect.intersectRectangle (r)) destRegion.rects.add (r); diff --git a/modules/juce_graphics/images/juce_Image.h b/modules/juce_graphics/images/juce_Image.h index 5e3b6700..10d2c360 100644 --- a/modules/juce_graphics/images/juce_Image.h +++ b/modules/juce_graphics/images/juce_Image.h @@ -326,13 +326,13 @@ public: The coordinate you provide here isn't checked, so it's the caller's responsibility to make sure it's not out-of-range. */ - inline uint8* getLinePointer (int y) const noexcept { return data + y * lineStride; } + inline uint8* getLinePointer (int y) const noexcept { return data + (size_t) y * (size_t) lineStride; } /** Returns a pointer to a pixel in the image. The coordinates you give here are not checked, so it's the caller's responsibility to make sure they're not out-of-range. */ - inline uint8* getPixelPointer (int x, int y) const noexcept { return data + y * lineStride + x * pixelStride; } + inline uint8* getPixelPointer (int x, int y) const noexcept { return data + (size_t) y * (size_t) lineStride + (size_t) x * (size_t) pixelStride; } /** Returns the colour of a given pixel. For performance reasons, this won't do any bounds-checking on the coordinates, so it's the caller's diff --git a/modules/juce_graphics/juce_graphics.h b/modules/juce_graphics/juce_graphics.h index 1617a6df..87d08424 100644 --- a/modules/juce_graphics/juce_graphics.h +++ b/modules/juce_graphics/juce_graphics.h @@ -35,7 +35,7 @@ ID: juce_graphics vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE graphics classes description: Classes for 2D vector graphics, image loading/saving, font handling, etc. website: http://www.juce.com/juce diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm index 16ca13e6..f34002a6 100644 --- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm +++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm @@ -629,8 +629,8 @@ void CoreGraphicsContext::setFont (const Font& newFont) auto cgTransformToJuceTransform = [](CGAffineTransform& t) -> AffineTransform { - return { (float) t.a, (float) t.b, (float) t.tx, - (float) t.c, (float) t.d, (float) t.ty }; + return { (float) t.a, (float) t.c, (float) t.tx, + (float) t.b, (float) t.d, (float) t.ty }; }; state->fontTransform = cgTransformToJuceTransform (fontTransform); @@ -649,7 +649,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra { if (state->fontRef != nullptr && state->fillType.isColour()) { - if (transform.isOnlyTranslation()) + if (transform.isOnlyTranslation() && state->fontTransform.isOnlyTranslation()) { auto t = transform.followedBy (state->inverseFontTransform); diff --git a/modules/juce_graphics/native/juce_mac_Fonts.mm b/modules/juce_graphics/native/juce_mac_Fonts.mm index 74bbfa49..6ae7035d 100644 --- a/modules/juce_graphics/native/juce_mac_Fonts.mm +++ b/modules/juce_graphics/native/juce_mac_Fonts.mm @@ -41,7 +41,7 @@ namespace CoreTextTypeLayout if (! availableStyles.contains (style)) { if (font.isItalic()) // Fake-up an italic font if there isn't a real one. - requiredTransform = CGAffineTransformMake (1.0f, 0, 0.25f, 1.0f, 0, 0); + requiredTransform = CGAffineTransformMake (1.0f, 0, 0.1f, 1.0f, 0, 0); return availableStyles[0]; } diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h index 2e6a9dcd..e6c0b74a 100644 --- a/modules/juce_gui_basics/juce_gui_basics.h +++ b/modules/juce_gui_basics/juce_gui_basics.h @@ -35,7 +35,7 @@ ID: juce_gui_basics vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE GUI core classes description: Basic user-interface components and related classes. website: http://www.juce.com/juce diff --git a/modules/juce_gui_basics/layout/juce_Grid.cpp b/modules/juce_gui_basics/layout/juce_Grid.cpp index b3574111..e239e80c 100644 --- a/modules/juce_gui_basics/layout/juce_Grid.cpp +++ b/modules/juce_gui_basics/layout/juce_Grid.cpp @@ -29,13 +29,13 @@ namespace juce struct Grid::SizeCalculation { - static float getTotalAbsoluteSize (const juce::Array& tracks, Px gapSize) noexcept + static float getTotalAbsoluteSize (const Array& tracks, Px gapSize) noexcept { float totalCellSize = 0.0f; for (const auto& trackInfo : tracks) - if (! trackInfo.isFraction || trackInfo.hasKeyword) - totalCellSize += trackInfo.size; + if (! trackInfo.isFractional() || trackInfo.isAuto()) + totalCellSize += trackInfo.getSize(); float totalGap = tracks.size() > 1 ? static_cast ((tracks.size() - 1) * gapSize.pixels) : 0.0f; @@ -43,45 +43,45 @@ struct Grid::SizeCalculation return totalCellSize + totalGap; } - static float getRelativeUnitSize (float size, float totalAbsolute, const juce::Array& tracks) noexcept + static float getRelativeUnitSize (float size, float totalAbsolute, const Array& tracks) noexcept { - const float totalRelative = juce::jlimit (0.0f, size, size - totalAbsolute); + const float totalRelative = jlimit (0.0f, size, size - totalAbsolute); float factorsSum = 0.0f; for (const auto& trackInfo : tracks) - if (trackInfo.isFraction) - factorsSum += trackInfo.size; + if (trackInfo.isFractional()) + factorsSum += trackInfo.getSize(); jassert (factorsSum != 0.0f); return totalRelative / factorsSum; } //============================================================================== - static float getTotalAbsoluteHeight (const juce::Array& rowTracks, Px rowGap) + static float getTotalAbsoluteHeight (const Array& rowTracks, Px rowGap) { return getTotalAbsoluteSize (rowTracks, rowGap); } - static float getTotalAbsoluteWidth (const juce::Array& columnTracks, Px columnGap) + static float getTotalAbsoluteWidth (const Array& columnTracks, Px columnGap) { return getTotalAbsoluteSize (columnTracks, columnGap); } - static float getRelativeWidthUnit (float gridWidth, Px columnGap, const juce::Array& columnTracks) + static float getRelativeWidthUnit (float gridWidth, Px columnGap, const Array& columnTracks) { return getRelativeUnitSize (gridWidth, getTotalAbsoluteWidth (columnTracks, columnGap), columnTracks); } - static float getRelativeHeightUnit (float gridHeight, Px rowGap, const juce::Array& rowTracks) + static float getRelativeHeightUnit (float gridHeight, Px rowGap, const Array& rowTracks) { return getRelativeUnitSize (gridHeight, getTotalAbsoluteHeight (rowTracks, rowGap), rowTracks); } //============================================================================== - static bool hasAnyFractions (const juce::Array& tracks) + static bool hasAnyFractions (const Array& tracks) { for (auto& t : tracks) - if (t.isFraction) + if (t.isFractional()) return true; return false; @@ -89,8 +89,8 @@ struct Grid::SizeCalculation void computeSizes (float gridWidth, float gridHeight, Px columnGapToUse, Px rowGapToUse, - const juce::Array& columnTracks, - const juce::Array& rowTracks) + const Array& columnTracks, + const Array& rowTracks) { if (hasAnyFractions (columnTracks)) relativeWidthUnit = getRelativeWidthUnit (gridWidth, columnGapToUse, columnTracks); @@ -118,19 +118,19 @@ struct Grid::PlacementHelpers //============================================================================== struct LineRange { int start, end; }; struct LineArea { LineRange column, row; }; - struct LineInfo { juce::StringArray lineNames; }; + struct LineInfo { StringArray lineNames; }; struct NamedArea { - juce::String name; + String name; LineArea lines; }; //============================================================================== - static juce::Array getArrayOfLinesFromTracks (const juce::Array& tracks) + static Array getArrayOfLinesFromTracks (const Array& tracks) { // fill line info array - juce::Array lines; + Array lines; for (int i = 1; i <= tracks.size(); ++i) { @@ -139,7 +139,7 @@ struct Grid::PlacementHelpers if (i == 1) // start line { LineInfo li; - li.lineNames.add (currentTrack.startLineName); + li.lineNames.add (currentTrack.getStartLineName()); lines.add (li); } @@ -148,8 +148,8 @@ struct Grid::PlacementHelpers const auto& prevTrack = tracks.getReference (i - 2); LineInfo li; - li.lineNames.add (prevTrack.endLineName); - li.lineNames.add (currentTrack.startLineName); + li.lineNames.add (prevTrack.getEndLineName()); + li.lineNames.add (currentTrack.getStartLineName()); lines.add (li); } @@ -157,7 +157,7 @@ struct Grid::PlacementHelpers if (i == tracks.size()) // end line { LineInfo li; - li.lineNames.add (currentTrack.endLineName); + li.lineNames.add (currentTrack.getEndLineName()); lines.add (li); } } @@ -169,7 +169,7 @@ struct Grid::PlacementHelpers //============================================================================== static int deduceAbsoluteLineNumberFromLineName (GridItem::Property prop, - const juce::Array& tracks) + const Array& tracks) { jassert (prop.hasAbsolute()); @@ -180,14 +180,14 @@ struct Grid::PlacementHelpers { for (const auto& name : lines.getReference (i).lineNames) { - if (prop.name == name) + if (prop.getName() == name) { ++count; break; } } - if (count == prop.number) + if (count == prop.getNumber()) return i + 1; } @@ -196,19 +196,19 @@ struct Grid::PlacementHelpers } static int deduceAbsoluteLineNumber (GridItem::Property prop, - const juce::Array& tracks) + const Array& tracks) { jassert (prop.hasAbsolute()); if (prop.hasName()) return deduceAbsoluteLineNumberFromLineName (prop, tracks); - return prop.number > 0 ? prop.number : tracks.size() + 2 + prop.number; + return prop.getNumber() > 0 ? prop.getNumber() : tracks.size() + 2 + prop.getNumber(); } static int deduceAbsoluteLineNumberFromNamedSpan (int startLineNumber, GridItem::Property propertyWithSpan, - const juce::Array& tracks) + const Array& tracks) { jassert (propertyWithSpan.hasSpan()); @@ -219,14 +219,14 @@ struct Grid::PlacementHelpers { for (const auto& name : lines.getReference (i).lineNames) { - if (propertyWithSpan.name == name) + if (propertyWithSpan.getName() == name) { ++count; break; } } - if (count == propertyWithSpan.number) + if (count == propertyWithSpan.getNumber()) return i + 1; } @@ -236,18 +236,18 @@ struct Grid::PlacementHelpers static int deduceAbsoluteLineNumberBasedOnSpan (int startLineNumber, GridItem::Property propertyWithSpan, - const juce::Array& tracks) + const Array& tracks) { jassert (propertyWithSpan.hasSpan()); if (propertyWithSpan.hasName()) return deduceAbsoluteLineNumberFromNamedSpan (startLineNumber, propertyWithSpan, tracks); - return startLineNumber + propertyWithSpan.number; + return startLineNumber + propertyWithSpan.getNumber(); } //============================================================================== - static LineRange deduceLineRange (GridItem::StartAndEndProperty prop, const juce::Array& tracks) + static LineRange deduceLineRange (GridItem::StartAndEndProperty prop, const Array& tracks) { LineRange s; @@ -295,7 +295,7 @@ struct Grid::PlacementHelpers static LineArea deduceLineArea (const GridItem& item, const Grid& grid, - const std::map& namedAreas) + const std::map& namedAreas) { if (item.area.isNotEmpty() && ! grid.templateAreas.isEmpty()) { @@ -310,12 +310,12 @@ struct Grid::PlacementHelpers } //============================================================================== - static juce::Array parseAreasProperty (const juce::StringArray& areasStrings) + static Array parseAreasProperty (const StringArray& areasStrings) { - juce::Array strings; + Array strings; for (const auto& areaString : areasStrings) - strings.add (juce::StringArray::fromTokens (areaString, false)); + strings.add (StringArray::fromTokens (areaString, false)); if (strings.size() > 0) { @@ -328,7 +328,7 @@ struct Grid::PlacementHelpers return strings; } - static NamedArea findArea (juce::Array& stringsArrays) + static NamedArea findArea (Array& stringsArrays) { NamedArea area; @@ -370,11 +370,11 @@ struct Grid::PlacementHelpers } //============================================================================== - static std::map deduceNamedAreas (const juce::StringArray& areasStrings) + static std::map deduceNamedAreas (const StringArray& areasStrings) { auto stringsArrays = parseAreasProperty (areasStrings); - std::map areas; + std::map areas; for (auto area = findArea (stringsArrays); area.name.isNotEmpty(); area = findArea (stringsArrays)) { @@ -389,19 +389,19 @@ struct Grid::PlacementHelpers } //============================================================================== - static float getCoord (int trackNumber, float relativeUnit, Px gap, const juce::Array& tracks) + static float getCoord (int trackNumber, float relativeUnit, Px gap, const Array& tracks) { float c = 0; for (const auto* it = tracks.begin(); it != tracks.begin() + trackNumber - 1; ++it) - c += (it->isFraction ? it->size * relativeUnit : it->size) + static_cast (gap.pixels); + c += it->getAbsoluteSize (relativeUnit) + static_cast (gap.pixels); return c; } - static juce::Rectangle getCellBounds (int columnNumber, int rowNumber, - const juce::Array& columnTracks, - const juce::Array& rowTracks, + static Rectangle getCellBounds (int columnNumber, int rowNumber, + const Array& columnTracks, + const Array& rowTracks, Grid::SizeCalculation calculation, Px columnGap, Px rowGap) { @@ -412,17 +412,15 @@ struct Grid::PlacementHelpers const auto y = getCoord (rowNumber, calculation.relativeHeightUnit, rowGap, rowTracks); const auto& columnTrackInfo = columnTracks.getReference (columnNumber - 1); - const float width = columnTrackInfo.isFraction ? columnTrackInfo.size * calculation.relativeWidthUnit - : columnTrackInfo.size; + const float width = columnTrackInfo.getAbsoluteSize (calculation.relativeWidthUnit); const auto& rowTrackInfo = rowTracks.getReference (rowNumber - 1); - const float height = rowTrackInfo.isFraction ? rowTrackInfo.size * calculation.relativeHeightUnit - : rowTrackInfo.size; + const float height = rowTrackInfo.getAbsoluteSize (calculation.relativeHeightUnit); return { x, y, width, height }; } - static juce::Rectangle alignCell (juce::Rectangle area, + static Rectangle alignCell (Rectangle area, int columnNumber, int rowNumber, int numberOfColumns, int numberOfRows, Grid::SizeCalculation calculation, @@ -486,10 +484,10 @@ struct Grid::PlacementHelpers return area; } - static juce::Rectangle getAreaBounds (int columnLineNumberStart, int columnLineNumberEnd, + static Rectangle getAreaBounds (int columnLineNumberStart, int columnLineNumberEnd, int rowLineNumberStart, int rowLineNumberEnd, - const juce::Array& columnTracks, - const juce::Array& rowTracks, + const Array& columnTracks, + const Array& rowTracks, Grid::SizeCalculation calculation, Grid::AlignContent alignContent, Grid::JustifyContent justifyContent, @@ -529,7 +527,7 @@ struct Grid::PlacementHelpers //============================================================================== struct Grid::AutoPlacement { - using ItemPlacementArray = juce::Array>; + using ItemPlacementArray = Array>; //============================================================================== struct OccupancyPlane @@ -722,10 +720,10 @@ struct Grid::AutoPlacement static int getSpanFromAuto (GridItem::StartAndEndProperty prop) { if (prop.end.hasSpan()) - return prop.end.number; + return prop.end.getNumber(); if (prop.start.hasSpan()) - return prop.start.number; + return prop.start.getNumber(); return 1; } @@ -735,12 +733,12 @@ struct Grid::AutoPlacement { const auto namedAreas = Grid::PlacementHelpers::deduceNamedAreas (grid.templateAreas); - OccupancyPlane plane (juce::jmax (grid.templateColumns.size() + 1, 2), - juce::jmax (grid.templateRows.size() + 1, 2), + OccupancyPlane plane (jmax (grid.templateColumns.size() + 1, 2), + jmax (grid.templateRows.size() + 1, 2), isColumnAutoFlow (grid.autoFlow)); ItemPlacementArray itemPlacementArray; - juce::Array sortedItems; + Array sortedItems; for (auto& item : grid.items) sortedItems.add (&item); @@ -836,12 +834,12 @@ struct Grid::AutoPlacement return { columnEndLine, rowEndLine }; } - static std::pair, juce::Array> createImplicitTracks (const Grid& grid, + static std::pair, Array> createImplicitTracks (const Grid& grid, const ItemPlacementArray& items) { const auto columnAndRowLineEnds = getHighestEndLinesNumbers (items); - juce::Array implicitColumnTracks, implicitRowTracks; + Array implicitColumnTracks, implicitRowTracks; for (int i = grid.templateColumns.size() + 1; i < columnAndRowLineEnds.first; i++) implicitColumnTracks.add (grid.autoColumns); @@ -853,8 +851,8 @@ struct Grid::AutoPlacement } //============================================================================== - static void applySizeForAutoTracks (juce::Array& columns, - juce::Array& rows, + static void applySizeForAutoTracks (Array& columns, + Array& rows, const ItemPlacementArray& itemPlacementArray) { auto isSpan = [](Grid::PlacementHelpers::LineRange r) -> bool { return std::abs (r.end - r.start) > 1; }; @@ -881,11 +879,11 @@ struct Grid::AutoPlacement }; for (int i = 0; i < rows.size(); i++) - if (rows.getReference (i).hasKeyword) + if (rows.getReference (i).isAuto()) rows.getReference (i).size = getHighestItemOnRow (i + 1, itemPlacementArray); for (int i = 0; i < columns.size(); i++) - if (columns.getReference (i).hasKeyword) + if (columns.getReference (i).isAuto()) columns.getReference (i).size = getHighestItemOnColumn (i + 1, itemPlacementArray); } }; @@ -893,9 +891,9 @@ struct Grid::AutoPlacement //============================================================================== struct Grid::BoxAlignment { - static juce::Rectangle alignItem (const GridItem& item, + static Rectangle alignItem (const GridItem& item, const Grid& grid, - juce::Rectangle area) + Rectangle area) { // if item align is auto, inherit value from grid Grid::AlignItems alignType = Grid::AlignItems::start; @@ -912,32 +910,26 @@ struct Grid::BoxAlignment justifyType = static_cast (item.justifySelf); // subtract margin from area - area = juce::BorderSize (item.margin.top, item.margin.left, item.margin.bottom, item.margin.right) + area = BorderSize (item.margin.top, item.margin.left, item.margin.bottom, item.margin.right) .subtractedFrom (area); // align and justify auto r = area; - if (item.width != (float) GridItem::notAssigned) - r.setWidth (item.width); - - if (item.height != (float) GridItem::notAssigned) - r.setHeight (item.height); + if (item.width != (float) GridItem::notAssigned) r.setWidth (item.width); + if (item.height != (float) GridItem::notAssigned) r.setHeight (item.height); + if (item.maxWidth != (float) GridItem::notAssigned) r.setWidth (jmin (item.maxWidth, r.getWidth())); + if (item.minWidth > 0.0f) r.setWidth (jmax (item.minWidth, r.getWidth())); + if (item.maxHeight != (float) GridItem::notAssigned) r.setHeight (jmin (item.maxHeight, r.getHeight())); + if (item.minHeight > 0.0f) r.setHeight (jmax (item.minHeight, r.getHeight())); if (alignType == Grid::AlignItems::start && justifyType == Grid::JustifyItems::start) return r; - if (alignType == Grid::AlignItems::end) - r.setY (r.getY() + (area.getHeight() - r.getHeight())); - - if (justifyType == Grid::JustifyItems::end) - r.setX (r.getX() + (area.getWidth() - r.getWidth())); - - if (alignType == Grid::AlignItems::center) - r.setCentre (r.getCentreX(), area.getCentreY()); - - if (justifyType == Grid::JustifyItems::center) - r.setCentre (area.getCentreX(), r.getCentreY()); + if (alignType == Grid::AlignItems::end) r.setY (r.getY() + (area.getHeight() - r.getHeight())); + if (justifyType == Grid::JustifyItems::end) r.setX (r.getX() + (area.getWidth() - r.getWidth())); + if (alignType == Grid::AlignItems::center) r.setCentre (r.getCentreX(), area.getCentreY()); + if (justifyType == Grid::JustifyItems::center) r.setCentre (area.getCentreX(), r.getCentreY()); return r; } @@ -950,44 +942,52 @@ Grid::TrackInfo::TrackInfo (Px sizeInPixels) noexcept : size (static_cast Grid::TrackInfo::TrackInfo (Fr fractionOfFreeSpace) noexcept : size ((float)fractionOfFreeSpace.fraction), isFraction (true) {} -Grid::TrackInfo::TrackInfo (Px sizeInPixels, const juce::String& endLineNameToUse) noexcept : Grid::TrackInfo (sizeInPixels) +Grid::TrackInfo::TrackInfo (Px sizeInPixels, const String& endLineNameToUse) noexcept : Grid::TrackInfo (sizeInPixels) { endLineName = endLineNameToUse; } -Grid::TrackInfo::TrackInfo (Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept : Grid::TrackInfo (fractionOfFreeSpace) +Grid::TrackInfo::TrackInfo (Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept : Grid::TrackInfo (fractionOfFreeSpace) { endLineName = endLineNameToUse; } -Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels) noexcept : Grid::TrackInfo (sizeInPixels) +Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Px sizeInPixels) noexcept : Grid::TrackInfo (sizeInPixels) { startLineName = startLineNameToUse; } -Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept : Grid::TrackInfo (fractionOfFreeSpace) +Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept : Grid::TrackInfo (fractionOfFreeSpace) { startLineName = startLineNameToUse; } -Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels, const juce::String& endLineNameToUse) noexcept +Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Px sizeInPixels, const String& endLineNameToUse) noexcept : Grid::TrackInfo (startLineNameToUse, sizeInPixels) { endLineName = endLineNameToUse; } -Grid::TrackInfo::TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept +Grid::TrackInfo::TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept : Grid::TrackInfo (startLineNameToUse, fractionOfFreeSpace) { endLineName = endLineNameToUse; } +float Grid::TrackInfo::getAbsoluteSize (float relativeFractionalUnit) const +{ + if (isFractional()) + return size * relativeFractionalUnit; + else + return size; +} + //============================================================================== Grid::Grid() noexcept {} Grid::~Grid() noexcept {} //============================================================================== -void Grid::performLayout (juce::Rectangle targetArea) +void Grid::performLayout (Rectangle targetArea) { const auto itemsAndAreas = Grid::AutoPlacement().deduceAllItems (*this); diff --git a/modules/juce_gui_basics/layout/juce_Grid.h b/modules/juce_gui_basics/layout/juce_Grid.h index 86e87719..64c5d3e0 100644 --- a/modules/juce_gui_basics/layout/juce_Grid.h +++ b/modules/juce_gui_basics/layout/juce_Grid.h @@ -67,35 +67,37 @@ public: { /** Creates a track with auto dimension. */ TrackInfo() noexcept; - /** */ + TrackInfo (Px sizeInPixels) noexcept; - /** */ TrackInfo (Fr fractionOfFreeSpace) noexcept; - /** */ - TrackInfo (Px sizeInPixels, const juce::String& endLineNameToUse) noexcept; - /** */ - TrackInfo (Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept; + TrackInfo (Px sizeInPixels, const String& endLineNameToUse) noexcept; + TrackInfo (Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept; + + TrackInfo (const String& startLineNameToUse, Px sizeInPixels) noexcept; + TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept; + + TrackInfo (const String& startLineNameToUse, Px sizeInPixels, const String& endLineNameToUse) noexcept; + TrackInfo (const String& startLineNameToUse, Fr fractionOfFreeSpace, const String& endLineNameToUse) noexcept; - /** */ - TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels) noexcept; - /** */ - TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace) noexcept; + bool isAuto() const noexcept { return hasKeyword; } + bool isFractional() const noexcept { return isFraction; } + bool isPixels() const noexcept { return ! isFraction; } + const String& getStartLineName() const noexcept { return startLineName; } + const String& getEndLineName() const noexcept { return endLineName; } - /** */ - TrackInfo (const juce::String& startLineNameToUse, Px sizeInPixels, const juce::String& endLineNameToUse) noexcept; - /** */ - TrackInfo (const juce::String& startLineNameToUse, Fr fractionOfFreeSpace, const juce::String& endLineNameToUse) noexcept; + /** Get the track's size - which might mean an absolute pixels value or a fractional ratio. */ + float getSize() const noexcept { return size; } private: friend class Grid; - friend class GridItem; + float getAbsoluteSize (float relativeFractionalUnit) const; float size = 0; // Either a fraction or an absolute size in pixels bool isFraction = false; bool hasKeyword = false; - juce::String startLineName, endLineName; + String startLineName, endLineName; }; //============================================================================== @@ -177,13 +179,13 @@ public: //============================================================================== /** The set of column tracks to lay out. */ - juce::Array templateColumns; + Array templateColumns; /** The set of row tracks to lay out. */ - juce::Array templateRows; + Array templateRows; /** Template areas */ - juce::StringArray templateAreas; + StringArray templateAreas; /** The row track for auto dimension. */ TrackInfo autoRows; @@ -201,11 +203,11 @@ public: //============================================================================== /** The set of items to lay-out. */ - juce::Array items; + Array items; //============================================================================== /** Lays-out the grid's items within the given rectangle. */ - void performLayout (juce::Rectangle); + void performLayout (Rectangle); //============================================================================== /** Returns the number of columns. */ diff --git a/modules/juce_gui_basics/layout/juce_GridItem.cpp b/modules/juce_gui_basics/layout/juce_GridItem.cpp index da6c9356..f85e0d85 100644 --- a/modules/juce_gui_basics/layout/juce_GridItem.cpp +++ b/modules/juce_gui_basics/layout/juce_GridItem.cpp @@ -36,11 +36,11 @@ GridItem::Property::Property (GridItem::Keyword keyword) noexcept : isAuto (keyw jassert (keyword == GridItem::Keyword::autoValue); } -GridItem::Property::Property (const char* lineNameToUse) noexcept : GridItem::Property (juce::String (lineNameToUse)) +GridItem::Property::Property (const char* lineNameToUse) noexcept : GridItem::Property (String (lineNameToUse)) { } -GridItem::Property::Property (const juce::String& lineNameToUse) noexcept : name (lineNameToUse), number (1) +GridItem::Property::Property (const String& lineNameToUse) noexcept : name (lineNameToUse), number (1) { } @@ -48,7 +48,7 @@ GridItem::Property::Property (int numberToUse) noexcept : number (numberToUse) { } -GridItem::Property::Property (int numberToUse, const juce::String& lineNameToUse) noexcept +GridItem::Property::Property (int numberToUse, const String& lineNameToUse) noexcept : name (lineNameToUse), number (numberToUse) { } @@ -72,8 +72,8 @@ GridItem::Margin::Margin (float t, float r, float b, float l) noexcept : left (l GridItem::GridItem() noexcept {} GridItem::~GridItem() noexcept {} -GridItem::GridItem (juce::Component& componentToUse) noexcept : associatedComponent (&componentToUse) {} -GridItem::GridItem (juce::Component* componentToUse) noexcept : associatedComponent (componentToUse) {} +GridItem::GridItem (Component& componentToUse) noexcept : associatedComponent (&componentToUse) {} +GridItem::GridItem (Component* componentToUse) noexcept : associatedComponent (componentToUse) {} void GridItem::setArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd) { @@ -89,7 +89,7 @@ void GridItem::setArea (Property rowStart, Property columnStart) row.start = rowStart; } -void GridItem::setArea (const juce::String& areaName) +void GridItem::setArea (const String& areaName) { area = areaName; } @@ -108,7 +108,7 @@ GridItem GridItem::withArea (Property rowStart, Property columnStart) const noex return gi; } -GridItem GridItem::withArea (const juce::String& areaName) const noexcept +GridItem GridItem::withArea (const String& areaName) const noexcept { auto gi = *this; gi.setArea (areaName); diff --git a/modules/juce_gui_basics/layout/juce_GridItem.h b/modules/juce_gui_basics/layout/juce_GridItem.h index 30f95c6e..93613348 100644 --- a/modules/juce_gui_basics/layout/juce_GridItem.h +++ b/modules/juce_gui_basics/layout/juce_GridItem.h @@ -48,57 +48,50 @@ public: jassert (numberToUse > 0); } - explicit Span (int numberToUse, const juce::String& nameToUse) : Span (numberToUse) + explicit Span (int numberToUse, const String& nameToUse) : Span (numberToUse) { /* Name must not be empty */ jassert (nameToUse.isNotEmpty()); name = nameToUse; } - explicit Span (const juce::String& nameToUse) : name (nameToUse) + explicit Span (const String& nameToUse) : name (nameToUse) { /* Name must not be empty */ jassert (nameToUse.isNotEmpty()); } int number = 1; - juce::String name; + String name; }; //============================================================================== /** Represents a property. */ struct Property { - /** */ Property() noexcept; - /** */ Property (Keyword keyword) noexcept; - /** */ Property (const char* lineNameToUse) noexcept; - /** */ - Property (const juce::String& lineNameToUse) noexcept; + Property (const String& lineNameToUse) noexcept; - /** */ Property (int numberToUse) noexcept; - /** */ - Property (int numberToUse, const juce::String& lineNameToUse) noexcept; + Property (int numberToUse, const String& lineNameToUse) noexcept; - /** */ Property (Span spanToUse) noexcept; - private: - bool hasSpan() const noexcept { return isSpan && ! isAuto; } - bool hasAbsolute() const noexcept { return ! (isSpan || isAuto); } - bool hasAuto() const noexcept { return isAuto; } - bool hasName() const noexcept { return name.isNotEmpty(); } - - friend class Grid; + bool hasSpan() const noexcept { return isSpan && ! isAuto; } + bool hasAbsolute() const noexcept { return ! (isSpan || isAuto); } + bool hasAuto() const noexcept { return isAuto; } + bool hasName() const noexcept { return name.isNotEmpty(); } + const String& getName() const noexcept { return name; } + int getNumber() const noexcept { return number; } - juce::String name; + private: + String name; int number = 1; /** Either an absolute line number or number of lines to span across. */ bool isSpan = false; bool isAuto = false; @@ -132,16 +125,16 @@ public: /** Creates an item with default parameters. */ GridItem() noexcept; /** Creates an item with a given Component to use. */ - GridItem (juce::Component& componentToUse) noexcept; + GridItem (Component& componentToUse) noexcept; /** Creates an item with a given Component to use. */ - GridItem (juce::Component* componentToUse) noexcept; + GridItem (Component* componentToUse) noexcept; /** Destructor. */ ~GridItem() noexcept; //============================================================================== /** If this is non-null, it represents a Component whose bounds are controlled by this item. */ - juce::Component* associatedComponent = nullptr; + Component* associatedComponent = nullptr; //============================================================================== /** Determines the order used to lay out items in their grid container. */ @@ -164,7 +157,7 @@ public: StartAndEndProperty row = { Keyword::autoValue, Keyword::autoValue }; /** */ - juce::String area; + String area; //============================================================================== enum @@ -174,12 +167,12 @@ public: }; /* TODO: move all of this into a common class that is shared with the FlexItem */ - float width = notAssigned; - float minWidth = 0; + float width = notAssigned; + float minWidth = 0.0f; float maxWidth = notAssigned; - float height = notAssigned; - float minHeight = 0; + float height = notAssigned; + float minHeight = 0.0f; float maxHeight = notAssigned; /** Represents a margin. */ @@ -200,7 +193,7 @@ public: Margin margin; /** The item's current bounds. */ - juce::Rectangle currentBounds; + Rectangle currentBounds; /** Short-hand */ void setArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd); @@ -209,7 +202,7 @@ public: void setArea (Property rowStart, Property columnStart); /** Short-hand */ - void setArea (const juce::String& areaName); + void setArea (const String& areaName); /** Short-hand */ GridItem withArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd) const noexcept; @@ -218,7 +211,7 @@ public: GridItem withArea (Property rowStart, Property columnStart) const noexcept; /** Short-hand */ - GridItem withArea (const juce::String& areaName) const noexcept; + GridItem withArea (const String& areaName) const noexcept; /** Returns a copy of this object with a new row property. */ GridItem withRow (StartAndEndProperty row) const noexcept; diff --git a/modules/juce_gui_basics/layout/juce_SidePanel.cpp b/modules/juce_gui_basics/layout/juce_SidePanel.cpp index 70c21dc1..e674a52d 100644 --- a/modules/juce_gui_basics/layout/juce_SidePanel.cpp +++ b/modules/juce_gui_basics/layout/juce_SidePanel.cpp @@ -219,7 +219,7 @@ void SidePanel::mouseUp (const MouseEvent&) } } -//========================================================================== +//============================================================================== void SidePanel::lookAndFeelChanged() { auto& lf = getLookAndFeel(); diff --git a/modules/juce_gui_basics/layout/juce_SidePanel.h b/modules/juce_gui_basics/layout/juce_SidePanel.h index 9753ab6b..263f55ef 100644 --- a/modules/juce_gui_basics/layout/juce_SidePanel.h +++ b/modules/juce_gui_basics/layout/juce_SidePanel.h @@ -181,8 +181,8 @@ public: titleTextColour = 0x100f002, shadowBaseColour = 0x100f003, dismissButtonNormalColour = 0x100f004, - dismissButtonOverColour = 0x100f004, - dismissButtonDownColour = 0x100f005 + dismissButtonOverColour = 0x100f005, + dismissButtonDownColour = 0x100f006 }; //============================================================================== @@ -193,7 +193,7 @@ public: std::function onPanelShowHide; private: - //========================================================================== + //============================================================================== Component* parent = nullptr; OptionalScopedPointer contentComponent; OptionalScopedPointer titleBarComponent; @@ -216,7 +216,7 @@ private: bool shouldShowDismissButton = true; - //========================================================================== + //============================================================================== void lookAndFeelChanged() override; void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override; diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index 6b470103..cbd79a66 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -80,7 +80,10 @@ struct ItemComponent : public Component customComp = *new HeaderItemComponent (item.text); if (customComp != nullptr) + { + setItem (*customComp, &item); addAndMakeVisible (*customComp); + } parent.addAndMakeVisible (this); @@ -96,6 +99,9 @@ struct ItemComponent : public Component ~ItemComponent() override { + if (customComp != nullptr) + setItem (*customComp, nullptr); + removeChildComponent (customComp.get()); } @@ -1589,6 +1595,7 @@ void PopupMenu::addSeparator() void PopupMenu::addSectionHeader (String title) { Item i (std::move (title)); + i.itemID = 0; i.isSectionHeader = true; addItem (std::move (i)); } @@ -1892,6 +1899,12 @@ void PopupMenu::setLookAndFeel (LookAndFeel* const newLookAndFeel) lookAndFeel = newLookAndFeel; } +void PopupMenu::setItem (CustomComponent& c, const Item* itemToUse) +{ + c.item = itemToUse; + c.repaint(); +} + //============================================================================== PopupMenu::CustomComponent::CustomComponent (bool autoTrigger) : triggeredAutomatically (autoTrigger) diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.h b/modules/juce_gui_basics/menus/juce_PopupMenu.h index 6da361ab..95c6661f 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.h +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.h @@ -699,6 +699,13 @@ public: */ bool isItemHighlighted() const noexcept { return isHighlighted; } + /** Returns a pointer to the Item that holds this custom component, if this + component is currently held by an Item. + You can query the Item for information that you might want to use + in your paint() method, such as the item's enabled and ticked states. + */ + const PopupMenu::Item* getItem() const noexcept { return item; } + /** @internal */ bool isTriggeredAutomatically() const noexcept { return triggeredAutomatically; } /** @internal */ @@ -707,6 +714,9 @@ public: private: //============================================================================== bool isHighlighted = false, triggeredAutomatically; + const PopupMenu::Item* item = nullptr; + + friend PopupMenu; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomComponent) }; @@ -812,6 +822,8 @@ private: Component* createWindow (const Options&, ApplicationCommandManager**) const; int showWithOptionalCallback (const Options&, ModalComponentManager::Callback*, bool); + static void setItem (CustomComponent&, const Item*); + #if JUCE_CATCH_DEPRECATED_CODE_MISUSE // These methods have new implementations now - see its new definition int drawPopupMenuItem (Graphics&, int, int, bool, bool, bool, bool, bool, const String&, const String&, Image*, const Colour*) { return 0; } diff --git a/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp b/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp index 16ee696b..b985f3d4 100644 --- a/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp +++ b/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp @@ -30,60 +30,82 @@ namespace juce // This byte-code is generated from native/javacore/app/com/roli/juce/JuceSharingContentProvider.java with min sdk version 16 // See juce_core/native/java/README.txt on how to generate this byte-code. static const uint8 javaJuceSharingContentProvider[] = -{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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -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, -0,0}; +{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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +12,0,0,0,16,0,0,1,0,0,0,160,12,0,0,0,0}; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -533,7 +555,7 @@ public: //============================================================================== jobject openFile (const LocalRef& contentProvider, - const LocalRef& uri, const LocalRef& mode) + const LocalRef& uri, const LocalRef& mode) { ignoreUnused (mode); @@ -553,8 +575,8 @@ public: } jobject query (const LocalRef& contentProvider, const LocalRef& uri, - const LocalRef& projection, const LocalRef& selection, - const LocalRef& selectionArgs, const LocalRef& sortOrder) + const LocalRef& projection, const LocalRef& selection, + const LocalRef& selectionArgs, const LocalRef& sortOrder) { ignoreUnused (selection, selectionArgs, sortOrder); @@ -837,7 +859,7 @@ private: CALLBACK (contentSharerGetStreamTypes, "contentSharerGetStreamTypes", "(Landroid/net/Uri;Ljava/lang/String;)[Ljava/lang/String;") \ - DECLARE_JNI_CLASS_WITH_BYTECODE (JuceSharingContentProvider, "com/roli/juce/JuceSharingContentProvider", 16, javaJuceSharingContentProvider, sizeof(javaJuceSharingContentProvider)) + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceSharingContentProvider, "com/roli/juce/JuceSharingContentProvider", 16, javaJuceSharingContentProvider, sizeof (javaJuceSharingContentProvider)) #undef JNI_CLASS_MEMBERS static jobject JNICALL contentSharerQuery (JNIEnv*, jobject contentProvider, jobject uri, jobjectArray projection, diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 92700f9f..18be24d4 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -677,12 +677,29 @@ public: void handleBackButtonCallback() { + bool handled = false; + if (auto* app = JUCEApplicationBase::getInstance()) - app->backButtonPressed(); + handled = app->backButtonPressed(); if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) if (kiosk->getPeer() == this) setNavBarsHidden (navBarsHidden); + + if (! handled) + { + auto* env = getEnv(); + LocalRef activity (getCurrentActivity()); + + if (activity != nullptr) + { + jmethodID finishMethod = env->GetMethodID (AndroidActivity, "finish", "()V"); + + if (finishMethod != nullptr) + env->CallVoidMethod (activity.get(), finishMethod); + } + } + } void handleKeyboardHiddenCallback() diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp index 40e5e1cc..c44e331e 100644 --- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp @@ -958,6 +958,8 @@ static double getScaleForDisplay (const String& name, double dpi) if (scaleFactor > 0.0) return scaleFactor; + + return 1.0; } } } @@ -1259,10 +1261,13 @@ public: Point getScreenPosition (bool physical) const { + auto screenBounds = (parentWindow == 0 ? bounds + : bounds.translated (parentScreenPosition.x, parentScreenPosition.y)); + if (physical) - return Desktop::getInstance().getDisplays().logicalToPhysical (bounds.getTopLeft()); + return Desktop::getInstance().getDisplays().logicalToPhysical (screenBounds.getTopLeft()); - return bounds.getTopLeft(); + return screenBounds.getTopLeft(); } Rectangle getBounds() const override { return bounds; } @@ -2397,6 +2402,7 @@ private: friend class LinuxRepaintManager; Window windowH = {}, parentWindow = {}, keyProxy = {}; Rectangle bounds; + Point parentScreenPosition; Image taskbarImage; bool fullScreen = false, mapped = false, focused = false; Visual* visual = {}; @@ -2853,9 +2859,23 @@ private: ScopedXLock xlock (display); - if (XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth) && parentWindow == 0) - if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child)) - wx = wy = 0; + if (XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth)) + { + int rootX = 0, rootY = 0; + + if (! XTranslateCoordinates (display, windowH, root, 0, 0, &rootX, &rootY, &child)) + rootX = rootY = 0; + + if (parentWindow == 0) + { + wx = rootX; + wy = rootY; + } + else + { + parentScreenPosition = Desktop::getInstance().getDisplays().physicalToLogical (Point (rootX, rootY)); + } + } Rectangle physicalBounds (wx, wy, (int) ww, (int) wh); diff --git a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp index bbc565b7..30817dba 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp +++ b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp @@ -465,7 +465,10 @@ void CodeEditorComponent::paint (Graphics& g) g.fillAll (findColour (CodeEditorComponent::backgroundColourId)); auto gutterSize = getGutterSize(); - g.reduceClipRegion (gutterSize, 0, verticalScrollBar.getX() - gutterSize, horizontalScrollBar.getY()); + auto bottom = horizontalScrollBar.isVisible() ? horizontalScrollBar.getY() : getHeight(); + auto right = verticalScrollBar.isVisible() ? verticalScrollBar.getX() : getWidth(); + + g.reduceClipRegion (gutterSize, 0, right - gutterSize, bottom); g.setFont (font); diff --git a/modules/juce_gui_extra/juce_gui_extra.h b/modules/juce_gui_extra/juce_gui_extra.h index 3f76c6e1..22361051 100644 --- a/modules/juce_gui_extra/juce_gui_extra.h +++ b/modules/juce_gui_extra/juce_gui_extra.h @@ -35,7 +35,7 @@ ID: juce_gui_extra vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE extended GUI classes description: Miscellaneous GUI classes for specialised tasks. website: http://www.juce.com/juce diff --git a/modules/juce_gui_extra/misc/juce_PushNotifications.h b/modules/juce_gui_extra/misc/juce_PushNotifications.h index ec98d624..742486a5 100644 --- a/modules/juce_gui_extra/misc/juce_PushNotifications.h +++ b/modules/juce_gui_extra/misc/juce_PushNotifications.h @@ -50,7 +50,7 @@ public: JUCE_DECLARE_SINGLETON (PushNotifications, false) #endif - //========================================================================== + //============================================================================== /** Represents a notification that can be sent or received. */ struct Notification { @@ -107,7 +107,7 @@ public: /**@}*/ }; - //========================================================================== + //============================================================================== /** @name Common fields */ /**@{*/ @@ -149,7 +149,7 @@ public: /**@}*/ - //========================================================================== + //============================================================================== /** @name iOS only fields */ /**@{*/ @@ -161,7 +161,7 @@ public: /**@}*/ - //========================================================================== + //============================================================================== /** @name Android only fields */ /**@{*/ @@ -323,7 +323,7 @@ public: }; - //========================================================================== + //============================================================================== /** Describes settings we want to use for current device. Note that at the moment this is only used on iOS and partially on OSX. @@ -438,7 +438,7 @@ public: */ void requestSettingsUsed(); - //========================================================================== + //============================================================================== /** Android API level 26 or higher only: Represents notification channel through which notifications will be sent. Starting from Android API level 26, you should call setupChannels() at the start of your application, before posting any notifications. Then, when sending notifications, @@ -491,7 +491,7 @@ public: */ void setupChannels (const Array& groups, const Array& channels); - //========================================================================== + //============================================================================== /** iOS only: sends an asynchronous request to retrieve a list of notifications that were scheduled and not yet delivered. @@ -505,7 +505,7 @@ public: /** Unschedules all pending local notifications. iOS only. */ void removeAllPendingLocalNotifications(); - //========================================================================== + //============================================================================== /** Checks whether notifications are enabled for given application. On iOS and OSX this will always return true, use requestSettingsUsed() instead. */ @@ -535,7 +535,7 @@ public: /** Removes all notifications that were delivered. */ void removeAllDeliveredNotifications(); - //========================================================================== + //============================================================================== /** Retrieves current device token. Note, it is not a good idea to cache this token because it may change in the meantime. Always call this method to get the current token value. @@ -587,7 +587,7 @@ public: int timeToLive, const StringPairArray& additionalData); - //========================================================================== + //============================================================================== /** Register a listener (ideally on application startup) to receive information about notifications received and any callbacks to async functions called. */ diff --git a/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp b/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp index 41bd3de2..9d77b2cb 100644 --- a/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp +++ b/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp @@ -189,7 +189,7 @@ DECLARE_JNI_CLASS_WITH_MIN_SDK (RemoteInputBuilder, "android/app/RemoteInput$Bui DECLARE_JNI_CLASS_WITH_MIN_SDK (StatusBarNotification, "android/service/notification/StatusBarNotification", 23) #undef JNI_CLASS_MEMBERS -//========================================================================== +//============================================================================== #if defined(JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME) #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ STATICMETHOD (getInstance, "getInstance", "()Lcom/google/firebase/iid/FirebaseInstanceId;") \ @@ -265,7 +265,7 @@ bool PushNotifications::Notification::isValid() const noexcept return isValidForPreApi26; } -//========================================================================== +//============================================================================== struct PushNotifications::Pimpl { Pimpl (PushNotifications& p) @@ -287,7 +287,7 @@ struct PushNotifications::Pimpl return true; } - //========================================================================== + //============================================================================== void sendLocalNotification (const PushNotifications::Notification& n) { // All required fields have to be setup! @@ -434,7 +434,7 @@ struct PushNotifications::Pimpl } } - //========================================================================== + //============================================================================== String getDeviceToken() const { #if defined(JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME) @@ -460,7 +460,7 @@ struct PushNotifications::Pimpl #endif } - //========================================================================== + //============================================================================== void subscribeToTopic (const String& topic) { #if defined(JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME) diff --git a/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp b/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp index 484f271a..f6d3253a 100644 --- a/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp +++ b/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp @@ -457,6 +457,10 @@ public: } receiver.reset (new CommandReceiver (this, inChannel)); + + pfds.push_back ({ threadControl[0], POLLIN, 0 }); + pfds.push_back ({ receiver->getFd(), POLLIN, 0 }); + startThread(); xembed.reset (new XEmbedComponent (windowHandle)); @@ -602,17 +606,10 @@ private: receiver->tryNextRead(); - fd_set set; - FD_ZERO (&set); - FD_SET (threadControl[0], &set); - FD_SET (receiver->getFd(), &set); - - int max_fd = jmax (threadControl[0], receiver->getFd()); - int result = 0; while (result == 0 || (result < 0 && errno == EINTR)) - result = select (max_fd + 1, &set, nullptr, nullptr, nullptr); + result = poll (&pfds.front(), static_cast (pfds.size()), 0); if (result < 0) break; @@ -702,6 +699,7 @@ private: int threadControl[2]; std::unique_ptr xembed; WaitableEvent threadBlocker; + std::vector pfds; }; //============================================================================== diff --git a/modules/juce_opengl/juce_opengl.h b/modules/juce_opengl/juce_opengl.h index d7343c38..19f67c98 100644 --- a/modules/juce_opengl/juce_opengl.h +++ b/modules/juce_opengl/juce_opengl.h @@ -35,7 +35,7 @@ ID: juce_opengl vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE OpenGL classes description: Classes for rendering OpenGL in a JUCE window. website: http://www.juce.com/juce diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index 1b6f0882..9850c115 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -296,6 +296,8 @@ public: transform = AffineTransform::scale ((float) newArea.getWidth() / (float) localBounds.getWidth(), (float) newArea.getHeight() / (float) localBounds.getHeight()); + nativeContext->updateWindowPosition (peer->getAreaCoveredBy (component)); + if (canTriggerUpdate) invalidateAll(); } diff --git a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp index 179d9b3a..23235a68 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp @@ -40,7 +40,11 @@ public: bool initialise() { - return frameBuffer.initialise (context, width, height); + if (! frameBuffer.initialise (context, width, height)) + return false; + + frameBuffer.clear (Colours::transparentBlack); + return true; } std::unique_ptr createLowLevelContext() override @@ -53,7 +57,12 @@ public: ImagePixelData::Ptr clone() override { - Image newImage (*new OpenGLFrameBufferImage (context, width, height)); + std::unique_ptr im (new OpenGLFrameBufferImage (context, width, height)); + + if (! im->initialise()) + return ImagePixelData::Ptr(); + + Image newImage (im.release()); Graphics g (newImage); g.drawImageAt (Image (*this), 0, 0, false); @@ -192,7 +201,6 @@ ImagePixelData::Ptr OpenGLImageType::create (Image::PixelFormat, int width, int if (! im->initialise()) return ImagePixelData::Ptr(); - im->frameBuffer.clear (Colours::transparentBlack); return *im.release(); } diff --git a/modules/juce_osc/juce_osc.h b/modules/juce_osc/juce_osc.h index 69740dfe..e4edc3d9 100644 --- a/modules/juce_osc/juce_osc.h +++ b/modules/juce_osc/juce_osc.h @@ -35,7 +35,7 @@ ID: juce_osc vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE OSC classes description: Open Sound Control implementation. website: http://www.juce.com/juce diff --git a/modules/juce_product_unlocking/juce_product_unlocking.h b/modules/juce_product_unlocking/juce_product_unlocking.h index d06dc64e..35033642 100644 --- a/modules/juce_product_unlocking/juce_product_unlocking.h +++ b/modules/juce_product_unlocking/juce_product_unlocking.h @@ -35,7 +35,7 @@ ID: juce_product_unlocking vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE Online marketplace support description: Classes for online product authentication website: http://www.juce.com/juce diff --git a/modules/juce_video/juce_video.h b/modules/juce_video/juce_video.h index 1e12c76c..dc1fd760 100644 --- a/modules/juce_video/juce_video.h +++ b/modules/juce_video/juce_video.h @@ -36,7 +36,7 @@ ID: juce_video vendor: juce - version: 5.4.4 + version: 5.4.5 name: JUCE video playback and capture classes description: Classes for playing video and capturing camera input. website: http://www.juce.com/juce @@ -57,7 +57,7 @@ //============================================================================== #include -//============================================================================= +//============================================================================== /** Config: JUCE_USE_CAMERA Enables camera support using the CameraDevice class (Mac, Windows, iOS, Android). */ @@ -79,7 +79,7 @@ #undef JUCE_USE_CAMERA #endif -//============================================================================= +//============================================================================== /** Config: JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME Enables synchronisation between video playback volume and OS media volume. Currently supported on Android only. @@ -98,6 +98,6 @@ #define JUCE_VIDEO_LOG(x) {} #endif -//============================================================================= +//============================================================================== #include "playback/juce_VideoComponent.h" #include "capture/juce_CameraDevice.h" diff --git a/modules/juce_video/native/juce_android_Video.h b/modules/juce_video/native/juce_android_Video.h index 7c7beead..5b64a881 100644 --- a/modules/juce_video/native/juce_android_Video.h +++ b/modules/juce_video/native/juce_android_Video.h @@ -1032,7 +1032,7 @@ private: } private: - //============================================================================= + //============================================================================== struct StateInfo { int playbackStateFlag = 0, allowedActions = 0; diff --git a/modules/juce_video/native/juce_win32_Video.h b/modules/juce_video/native/juce_win32_Video.h index 2e3e4a19..b162ba29 100644 --- a/modules/juce_video/native/juce_win32_Video.h +++ b/modules/juce_video/native/juce_win32_Video.h @@ -26,7 +26,7 @@ namespace VideoRenderers { - //====================================================================== + //============================================================================== struct Base { virtual ~Base() {} @@ -39,7 +39,7 @@ namespace VideoRenderers virtual HRESULT getVideoSize (long& videoWidth, long& videoHeight) = 0; }; - //====================================================================== + //============================================================================== struct VMR7 : public Base { VMR7() {} @@ -99,7 +99,7 @@ namespace VideoRenderers }; - //====================================================================== + //============================================================================== struct EVR : public Base { EVR() {} @@ -390,7 +390,7 @@ private: std::unique_ptr componentWatcher; - //====================================================================== + //============================================================================== struct DirectShowContext : public AsyncUpdater { DirectShowContext (Pimpl& c) : component (c) @@ -404,7 +404,7 @@ private: CoUninitialize(); } - //====================================================================== + //============================================================================== void updateWindowPosition (const Rectangle& newBounds) { nativeWindow->setWindowPosition (newBounds); @@ -415,7 +415,7 @@ private: nativeWindow->showWindow (shouldBeVisible); } - //====================================================================== + //============================================================================== void repaint() { if (hasVideo) @@ -434,7 +434,7 @@ private: videoRenderer->displayModeChanged(); } - //====================================================================== + //============================================================================== void peerChanged() { deleteNativeWindow(); @@ -489,7 +489,7 @@ private: triggerAsyncUpdate(); } - //====================================================================== + //============================================================================== Result loadFile (const String& fileOrURLPath) { jassert (state == uninitializedState); @@ -668,7 +668,7 @@ private: } } - //====================================================================== + //============================================================================== void play() { mediaControl->Run(); @@ -687,7 +687,7 @@ private: state = pausedState; } - //====================================================================== + //============================================================================== Rectangle getVideoSize() const noexcept { long width = 0, height = 0; @@ -698,7 +698,7 @@ private: return { (int) width, (int) height }; } - //====================================================================== + //============================================================================== double getDuration() const { REFTIME duration; @@ -744,7 +744,7 @@ private: State state = uninitializedState; private: - //====================================================================== + //============================================================================== enum { graphEventID = WM_APP + 0x43f0 }; Pimpl& component; @@ -762,7 +762,7 @@ private: bool hasVideo = false, needToUpdateViewport = true, needToRecreateNativeWindow = false; - //====================================================================== + //============================================================================== bool createNativeWindow() { jassert (nativeWindow == nullptr); @@ -839,7 +839,7 @@ private: return false; } - //====================================================================== + //============================================================================== struct NativeWindowClass : private DeletedAtShutdown { bool isRegistered() const noexcept { return atom != 0; } @@ -899,7 +899,7 @@ private: JUCE_DECLARE_NON_COPYABLE (NativeWindowClass) }; - //====================================================================== + //============================================================================== struct NativeWindow { NativeWindow (HWND parentToAddTo, void* userData) diff --git a/modules/juce_video/playback/juce_VideoComponent.cpp b/modules/juce_video/playback/juce_VideoComponent.cpp index 07ce04f3..8d01e1b5 100644 --- a/modules/juce_video/playback/juce_VideoComponent.cpp +++ b/modules/juce_video/playback/juce_VideoComponent.cpp @@ -51,29 +51,12 @@ VideoComponent::~VideoComponent() Result VideoComponent::load (const File& file) { - #if JUCE_ANDROID || JUCE_IOS - ignoreUnused (file); - jassertfalse; - return Result::fail ("load() is not supported on this platform. Use loadAsync() instead."); - #else - auto r = pimpl->load (file); - resized(); - return r; - #endif + return loadInternal (file, false); } Result VideoComponent::load (const URL& url) { - #if JUCE_ANDROID || JUCE_IOS - // You need to use loadAsync on Android & iOS. - ignoreUnused (url); - jassertfalse; - return Result::fail ("load() is not supported on this platform. Use loadAsync() instead."); - #else - auto r = pimpl->load (url); - resized(); - return r; - #endif + return loadInternal (url, false); } void VideoComponent::loadAsync (const URL& url, std::function callback) @@ -87,7 +70,7 @@ void VideoComponent::loadAsync (const URL& url, std::functionloadAsync (url, callback); #else - auto result = load (url); + auto result = loadInternal (url, true); callback (url, result); #endif } @@ -158,6 +141,27 @@ void VideoComponent::timerCallback() resized(); } +template +Result VideoComponent::loadInternal (const FileOrURL& fileOrUrl, bool loadAsync) +{ + #if JUCE_ANDROID || JUCE_IOS + ignoreUnused (fileOrUrl, loadAsync); + + // You need to use loadAsync on Android & iOS. + jassertfalse; + return Result::fail ("load() is not supported on this platform. Use loadAsync() instead."); + #else + auto result = pimpl->load (fileOrUrl); + + if (loadAsync) + startTimer (50); + else + resized(); + + return result; + #endif +} + #endif } // namespace juce diff --git a/modules/juce_video/playback/juce_VideoComponent.h b/modules/juce_video/playback/juce_VideoComponent.h index a41c169f..99f0a147 100644 --- a/modules/juce_video/playback/juce_VideoComponent.h +++ b/modules/juce_video/playback/juce_VideoComponent.h @@ -179,6 +179,9 @@ private: void resized() override; void timerCallback() override; + template + Result loadInternal (const FileOrURL&, bool); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VideoComponent) }; -- 2.30.2